best practices
1795 TopicsHow Microsoft Intune team upgraded a .NET service with GitHub Copilot modernization
Microsoft's Customer Zero blog series gives an insider view of how Microsoft builds and operates Microsoft using our trusted, enterprise-grade platform. Learn best practices from our engineering teams through real-world lessons, architectural patterns, and operational strategies for building, operating, and scaling AI-powered systems across the organization. A hosting platform transition gave our team an opportunity to modernize a Microsoft Intune enrollment service to .NET 8. I used GitHub Copilot modernization to assist with that work while retaining responsibility for design decisions and validation. Using GitHub Copilot modernization, I saved more than four weeks on the first library alone. The more durable outcome was the working method built around the agent: three working files that I kept alongside the code and owned myself, rather than leaving that state to the model, that let a months-long migration be paused, corrected and resumed without re-deriving the analysis every time. What follows is how that worked in practice, including where the agent stopped helping. The Challenge: retiring a hosting platform without carrying the framework forward My team owns a Platform as-a Service (PaaS) service that supports devices enrolling into Intune at the start of their enrollment journey. Microsoft Intune is a cloud-based endpoint management service that secures and manages an organization's devices and apps. It lets a company’s IT team manage and secure employees’ laptops, phones, tablets, apps, and company data from one central service. It supports Android, iOS/iPadOS, Linux, macOS, tvOS, visionOS, and Windows devices. This Service was running on .NET Framework 4.7.2, hosted on a non-AKS hosting platform. I moved it to Azure Kubernetes Service (AKS) hosting environment which is what started the work. The modernization combined two related but distinct changes: moving the workload to AKS and modernizing the application code to .NET. 8. The heaviest part was dependency mapping. A key part of the migration was mapping dependencies across shared libraries, namespaces, and APIs, including Intune owned and even team-owned libraries, some of which also needed modern .NET-compatible packages. The service had a substantial codebase with dependencies across multiple libraries, namespaces, and APIs. Some APIs were unchanged, some were renamed, and some had no direct replacement and required a design decision. These APIs were most often from internal Intune libraries. Without reusable mappings, those questions recur across projects and files. To maintain continuity across the migration as this was a long-term project, I kept an explicit record of decisions, completed work, and the next steps. The service spans several libraries and multiple endpoints that support about 20 plus different enrollment flows across Windows, Linux, Android, iOS, and macOS platforms. A single pull request covering the full migration was not possible, so I divided the work into increments small enough to review, test, and merge, or to isolate by enrollment flow, with a way to stop one day and pick up the next without paying the analysis cost twice. The Solution: a modernization agent with engineer-owned working content I started the side-by-side .NET framework service to .NET 8 service migration by hand, then brought in GitHub Copilot. In my early tests, I needed .NET migration-specific domain context beyond what I had established in my copilot session. The limitation was missing domain context, not an inability to generate code, and that is the gap a purpose-built tool closes. GitHub Copilot modernization is an agent built on GitHub Copilot, with Microsoft's language teams supplying domain knowledge. For .NET, its recommendations draw on current assembly and NuGet package analysis rather than relying only on patterns learned during model training. GitHub Copilot modernization is now available in Visual Studio, Visual Studio Code, GitHub Copilot CLI, GitHub Copilot app, and GitHub.com. When I did this migration, it was available only in Visual Studio and Visual Studio Code. For this migration, I chose GitHub Copilot modernization in Visual Studio through GitHub Copilot Chat in agent mode. I tested the modernization agent against work it could already check, running it over the same project and classes that I had migrated by hand and comparing the two. They were very close. That comparison, rather than anything in the tool's description, is what established enough confidence to point it at code nobody had migrated or analyzed manually yet. Once I started using the modernization agent, I realized that it was able to map .NET specific and global libraries as well as the API calls efficiently. The agent analyzed well but did not reliably retain migration state across sessions. Returning to the work could trigger a new assessment that overwrote prior artifacts. To avoid this, the more transferable part of my approach was the working context I built around the agent: a migration plan (migrationplan.md), a progress record (progress.md), and context notes. The agent generated a migrationPlan.md and progress.md at my request; I added the context from my notes from my previous sessions and manual migration and kept all three current in my local repository. The context preserved mappings I had already established by hand, so the agent could reuse settled decisions instead of researching them again. I kept them in my local repository rather than checking them in. The migrationplan.md broke the work into phases and day-sized tasks, and the progress.md file was updated after each increment. The next session could resume the recorded task instead of reassessing the codebase. When a migration increment surfaced a build issue, fixing it meant a side conversation, and the thread of the main work got lost in it. To avoid this, I started recording each failure under that day's task: what failed, what was tried, and what was ruled out. That gave the investigation somewhere to live without overwriting the main work. The current agents experience records task failures in progress-details.md. The Migrationplan.md is an editable markdown file, not opaque internal state, and I edited it when needed. Where a generated step was wrong for the service, or I wanted smaller increments of work per pull request, or to migrate a scenario before another, or to focus on one API path per pull request, or even to change the ordering, I updated the file with the correct information and the agent picked up the revision and carried on rather than reverting to its own plan. That made the editable plan especially useful when the migration approach changed. Plan granularity is also how I controlled pull request size. I used the plan to constrain each increment: for example, three model files and a view file, or one small end-to-end enrollment flow at a time, or one controller at a time, or sometimes not even a whole controller, just one API path, I made this judgement depending on the complexity of the scenario I wanted to migrate. Small increments stayed reviewable, and a broken build left a smaller surface to investigate. Supplying the build error and asking the agent to re-examine that increment produced a focused follow-up change. I began using the .NET modernize agent with an internal library, that supports Windows client calls made over Simple Object Access Protocol (SOAP). Before discovering the tool, I had already side-by-side migrated the .NET framework version of that library into another .NET8 successor library and had updated portions of the service’s windows enrollment flow. I used the mapping I had made between framework and .NET 8 libraries and APIs during this migration as a context for the tool, allowing each migration pass to reuse and add to the mappings established in previous one. The tool’s recommendations closely aligned with my manual migration approach on redo of the first library, which built my confidence in its output. I then used it for my next two internal library migrations, and the remaining Apple and Android enrollment flows in the service. The Impact: what the approach saved, and what it did not The internal library that handles Windows enrollment calls was estimated and took roughly six weeks of work but the tool completed it in one and a half weeks, a 75% schedule reduction, and on the second internal library dependency, also estimated at six weeks, I saved time again. I was able to reapply those savings to the remaining enrollment flows as I continued the service migration. The saving came from work that did not have to happen twice. Mappings settled in one phase were reused in the next rather than rediscovered. Project file conversion and NuGet package resolution, which is mechanical but voluminous, moved to the agent. What stayed with me was review, integration, the decisions, and the containerization and move to AKS itself. Without the agent, I would have needed to prioritize the migration more exclusively, which would have cut into the other project work I was delivering at the same time. Where the agent stopped helping In my experience, public libraries and Microsoft-wide libraries mapped well. Intune-internal libraries did not. In a subsequent internal prototype, I tested the agent on another service with different migration dependencies. For Intune-internal libraries, it could not identify which modern NuGet package or API replaced each dependency because those mappings were not available in its context. It still removed some of the mechanical work, but the mappings themselves stayed manual. During the prototype, I also built skills that work as a wrapper for the modernization agent that provides this internal migration context. I checked those skills into our internal repository so other Microsoft Intune engineering teams can use them internally through a plugin. What another team should take from this Validate it against work already done by hand to gain confidence. Running the agent over classes you have already migrated manually and comparing the output is cheap, and it gives you evidence for deciding whether to use the agent on code it has not yet migrated. Own the plan, not just the prompt. The agent writes its own plan and progress files to the repository. Read them and correct them, and it will follow your edits. For what it can't know, such as internal library mappings or your team's coding conventions, add a custom skill to the repository, and the agent will follow that too. Control pull request size through the plan rather than after the fact. Break pull requests into small increments. Scoping an increment to one controller, one API path, or a small end-to-end scenario keeps the change reviewable and testable, with a clear boundary for investigating migration issues. Reuse dependency mapping instead of rediscovering them. A large part of time savings come from carrying mappings established in previous phases into subsequent ones, even across libraries and services. Mechanical work like project conversion and NuGet package resolution can be handed off to the agent while you retained responsibility for integration, review and design decisions. Looking ahead The application-layer modernization is finished, while parity validation and the AKS traffic rollout continues. The reusable skills are checked into an internal repository and available to Intune engineering teams through an internal plugin, so another library or service can reuse established dependency-mapping work as well as Intune internal guidelines. I also shared the method and its measured time savings through Intune learning sessions, show and tell, Teams posts, and a newsletter. Learn more about GitHub Copilot modernization for .NET at https://dotnet.microsoft.com/platform/modernize and about Microsoft Intune at What is Microsoft Intune? - Microsoft Intune | Microsoft Learn.253Views0likes0CommentsNews to Know – Volume 3, Edition 11, October 2026
October brings clearer program setup and broader support for organizational-data integration, along with new private-preview opportunities for reporting and Copilot experiences. This edition covers what is available now and gives you an early look at administration, exports, insights, and survey management capabilities planned for the months ahead. New on your Viva Glint platform This section highlights new capabilities now available on your Viva Glint platform this month. Program setup: Clearer required-field indicators. Required fields throughout program setup now have visual indicators, making it easy to tell which fields are optional and which are required. Missed or skipped required fields will also be clearly identified. There have not been any changes to which fields are required and which are optional. Viva Glint Questions setup | Microsoft Learn Viva Glint integration with Microsoft 365 Organizational Data Service is rolling out to General Availability (GA) and will be available to all customers by the end of October. With GA, we are expanding support to a broader range of customer environments, including organizations with multiple Glint instances, MTO/CTS policies, and Microsoft 365 Government Community Cloud Moderate (GCC Moderate).The GA release also introduces several new capabilities, including email notifications, multiple connectors to support phased data ingestion, and Microsoft Purview integration for audit events, making it easier for organizations to manage, monitor, and govern their employee data integration. Coming soon to Viva Glint The following section offers an early look at capabilities coming to Glint in upcoming releases. Multi-attribute report exports for more roles | Private preview in October. Managers, leaders, analysts, and HR business partners in the private preview can export filtered, grouped, cross-dimensional report data for analysis outside Viva Glint. The update expands access beyond administrators and supports more flexible analysis while keeping permissions under administrative control. Viva Glint Multi-Attribute Export – Private Preview Sign-Up form Copilot Results Summarization | Private preview in early November. Results Summarization makes it easier for your managers and leaders to understand, explore, root cause and act on their Viva Glint results and comments. The Microsoft 365 Copilot Chat experience within Viva Glint brings together scores, benchmarks, changes, response rates, drivers, and comment themes for demographic breakdowns and segmented populations in one grounded conversation, so they can ask questions, spot patterns, make comparisons and dig deeper into your results. Join the private preview and help shape the experience through feedback sessions. Sign up here Continuous Engagement self-service administration | Private preview in November. Following additional engineering work, the administration update previously targeted for October is now planned for November. Existing private-preview customers will be able to map eligible workplace metrics to survey questions through a guided setup flow, reducing manual coordination and giving administrators more control over the context managers see with survey results. Comments export with attributes | Private preview planned for November. Private-preview participants will be able to export comments to Excel with selected respondent attributes, preserving the report’s filters and groupings. This will enable deeper analysis of comment themes across employee groups outside Viva Glint, while respecting users’ reporting permissions and applicable confidentiality safeguards. Copilot Highlights with workplace-metric context | Preview in December. Following updated development sequencing, this capability is now targeting December. When Continuous Engagement preview is enabled, Copilot Highlights will add selective workplace-metric callouts when an eligible behavioral signal provides useful context for a survey strength or opportunity, helping leaders identify where deeper investigation may be useful. Survey administration: Bulk removal of participants | Generally available in December. Building on the existing ability to remove participants in groups of 25, administrators will be able to remove closed surveys with no limit using a file upload When users are removed, their survey response will be permanently deleted. Removal events will also be recorded in audit logs, helping teams correct survey populations without relying on support. See our public roadmap for more feature updates. New Thought Leadership The Next Generation of Employee Listening Research Report | Available October 28. Organizations have more ways than ever to hear from employees, but more channels don't automatically lead to better decisions. Our latest research showed that 74% of enterprise listening leaders reported expanding their listening channels, yet only 1 in 3 rated their systems as strong at influencing business decisions and connecting listening data to meaningful outcomes. The report explores how listening teams can move from managing listening activity to building a right-fit system around what the organization needs to understand. The report will be the first release on Glint Labs, a new home for research, frameworks, and resources from the Microsoft People Science team. Look for the launch announcement on Viva Community on October 28. EECC session details In this recent EECC session, we previewed Results Summarization in Viva Glint Copilot Chat, an updated experience that brings survey scores and comment analysis together in a conversational interface. Customers saw how managers and leaders can ask plain-language questions about response rates, strengths, opportunities, trends, benchmarks, demographic differences, and comments, without first building reports or configuring filters. The session included a live product demonstration, an overview of the people-science research and evaluation shaping the experience, and details about the private preview. Participants discussed organizational guidance for AI-supported interpretation and action taking, administrative controls, licensing, confidentiality, presentation templates, language support, and practical preview limitations. Key takeaways from the discussion included: Results Summarization is the first milestone in a broader roadmap that moves from understanding survey findings to drafting, managing, and following up on manager action plans. The preview combines quantitative scores with comment summarization and can dynamically apply filters to answer questions about trends, benchmarks, demographics, and differences between employee groups. People-science guidance is built into the experience to promote accurate, relevant, clear, and calibrated interpretations, including appropriate context for group size, score changes, benchmarks, and correlation versus causation. Existing Viva Glint permissions, confidentiality thresholds, and suppression rules continue to apply; Copilot receives only aggregated results that have passed those protections. Customers emphasized the need for organization-specific guidance, approved action resources, company templates, and more granular administrative controls. These needs are being explored as part of the manager action-taking roadmap. The private preview is planned for participating customers beginning in November, with a recommended small-group rollout and a 30-minute feedback session for selected organizations. General availability is targeted for early next year. The capability supports the languages available in Viva Glint and currently works with the last two closed surveys for ad hoc and recurring programs. During preview, users should work from the Executive Summary report, select benchmarks in the report, use explicit prompts, and begin a new chat when context becomes too complex. If you are not yet a member of the Employee Experience Customer Connection (EECC) but would like to participate in upcoming sessions and gain access to other engaging and valuable Glint and Pulse customer activities, please sign up using the EECC opt-in form.128Views0likes0CommentsCloud Security Billing, Simplified: Introducing the Defender Workload Unit
That's the thinking behind an upcoming improvement to Microsoft Defender for Cloud: the Defender Workload Unit, or DWU. It's a new billing model and product experience that translates workload-specific usage into a common billing unit, with one unit price and one place to estimate and track costs. Why we’re improving our billing model We heard two things consistently: cloud security pricing can be complex, and tracking cost can take real work. DWU simplifies this with one unit price. Workload usage still converts behind the scenes. What changes is that organizations see a single unit and have one place to estimate, track, and explain cloud security spend. How DWU helps: Simplify pricing. Bring multiple workload-specific measures under one common billing model. Simplify onboarding and expansion. Make it easier to enable and extend protection across cloud environments. Match how you evaluate cloud security. Understand protection across your entire cloud environment, rather than workload by workload. Reduce cost-tracking friction. Make costs easier to estimate, track, and explain. One thing we deliberately kept unchanged: billing stays tied to what is used. How it compares DWU translates workload-specific usage into a common billing unit with a consistent per-unit price. Each workload continues to convert into DWUs according to its applicable usage measure. Workloads still count behind the scenes, including servers, databases, storage, containers, posture management, APIs, AI services, app services, Key Vault, and Azure Resource Manager. What changes are what customers see: one unit and one price. Workload-specific usage is converted into DWUs and aggregated across your environment, based on a consistent global per-unit price calculated hourly and billed monthly. Estimation, reporting, and billing use the same DWU framework, making it easier to understand how usage translates into cost. What changes is how customers estimate, buy, manage, and track consumption. DWU brings together changes to the billing model, supporting tools, and management experience. Here is how the new experience compares with the existing model. Existing PAYG model With DWU Estimating cost Manual mapping, plan by plan Signed-in estimator, formula visible. Sizing environment Manual inventory Read-only discovery script; your data stays with you Tracking spend Multiple billing signals Defender portal dashboard, detail in Azure Cost Management Database plans Multiple instance/hour-based plans A single instance/hour-based plan Containers pricing vCore-based pricing Per-node pricing APIs pricing Multiple plans A single plan at a reduced price Plan Management Azure portal only Defender portal only (based on customer scope selection) The benefits of DWU DWU is designed to make Defender for Cloud consumption easier to estimate and track by translating supported workload usage into a common billing unit. Actual consumption and cost will depend on your workload mix, usage, pricing arrangement, and applicable discounts. We are committing to pricing that's easier to understand and manage. Clearer cost planning. As your estate grows, you can watch how costs scale. Transparency you can show your finance team. The new cost estimator requires you to sign in and shows the pricing formula and how your estimate is calculated. The same ways to buy. DWU is available through Enterprise Agreement, Microsoft Customer Agreement Enterprise, Cloud Solution Provider, and buy-online channels. Streamlined onboarding. Enable selected Defender for Cloud plans across subscriptions and management scopes through a unified experience. Easier expansion. Extend protection as your cloud environment grows without introducing a new customer-facing pricing construct for every workload. More holistic visibility. Understand protection and consumption across your cloud environment, rather than workload by workload. What's new to help you A cost estimator. Enter resource quantities to receive an immediate list-price estimate. A path from estimate to deployment. The experience follows a simple flow: estimate, deploy, and track. Move directly from your estimate to deployment, then monitor cost through the Defender portal. A dashboard that answers the next question. See total spend, which workloads drive it, and how it trends over time. New pricing models for some workloads. Containers move from vCore-based pricing to per-node. APIs consolidate multiple plans into one with a reduced plan. Database workload protection is consolidated from multiple instance-per-hour plans into one. What stays in your control Simpler doesn't mean less flexible. Choose which workload plans to enable and change them at any time. In the product, tenant-level enablement applies to Azure subscriptions and management groups connected to the Defender portal. You can also enable plans for an individual connected management group or subscription. When you opt into a subscription, its workloads move together. Where to start A 30-day platform trial. Eligible subscriptions that are new to Cloud Security can start a Defender for Cloud trial in the Defender portal. The trial is optional, is granted at the subscription level, and is limited to one trial per subscription. It covers the full platform, including all plans, rather than one capability at a time. After the trial ends, billing begins for the subscription, unless all cloud security plans are disabled before the trial expires. Two questions worth bringing to your next planning review: How clearly can we estimate and explain Defender for Cloud consumption across supported workloads? If we cannot do so clearly, that's the gap DWU can close. When did we last compare our intended protection scope with our current cloud-resource inventory? The read-only discovery script can tell you, with nothing leaving your environment. One common unit and a more consistent way to estimate and track consumption can make it easier to understand and explain what you’re protecting. Learn more and get started Calculate your DWU estimates with the new Cloud Security Cost Estimator. Learn more about DWU and start onboarding. FAQ Does DWU cover multicloud environments? Initial support is focused on Azure, with broader multicloud and hybrid support planned over time. Does DWU cover Security Copilot? No, DWU does not offer coverage for Security Copilot. Can I use the new container and API models through the existing PAYG experience in Azure? No, they are available only through the DWU experience in the Defender portal.Making Azure Container Registry Activity Visible at Scale
Learn More Use Grafana dashboards in Azure Container Registry Monitor Azure Container Registry Azure Container Registry (ACR) now publishes two new metrics: Transactions and Data Transfer. For the first time, you can see which operations your registry serves, which region serves them, and how much data (egress) they move, for each registry and each of its geo-replicas. ACR often serves as a shared distribution point for containerized workloads. Build systems push container images and other artifacts, Kubernetes clusters pull images during deployments, and security and lifecycle tools scan artifacts throughout the day. As those environments grow, high-level signals such as a total pull count or storage used can tell you that activity changed, but not why. Transactions and Data Transfer fill that gap, so you can explain a traffic spike, catch a failing or throttled pipeline, and see where your data goes. A customer-facing metric is a stream of data points, attributed to one resource, that you can chart, split, and alert on in Azure Monitor. Building these metrics meant producing data points for very high-throughput signals, counting them accurately, attributing each one to the right registry in every region, and not exhausting the metrics system underneath. In this post, we'll cover what these metrics show you, what it took to deliver them at scale, and the sharded design that made it possible. What you couldn't see before Before this work, push and pull counts, alongside storage used, were the only registry traffic metrics we published. They showed that activity happened, but not what kind of operations drove it, whether each operation succeeded, or where it was served. Take a sudden jump in pulls: Before: total pull count is up, with no way to tell which geo-replication drove the traffic. Now: the extra requests are blob downloads in one geo-replication region, many of them Throttled, while Data Transfer from that geo-replication stays flat. Those gaps matter most when traffic changes. An increase may come from a deployment, a retry loop, metadata polling, a regional workload shift, or larger image layers, and each looks different underneath: a surge in manifest and blob reads, repeated errors or throttled responses, a steady stream of tag and listing calls, traffic moving between replicas, or more bytes per pull without more requests. To tell them apart, you need to know which operations are changing, how much artifact data is moving, where requests are being served, and whether the pattern matches the workload you intended to run. Push and pull counts summarize outcomes. Transactions and Data Transfer describe behavior, and describing behavior takes far more data. Why scale is the hard part These signals are high throughput by nature, because every counted request becomes its own data point: a single sampled registry's activity can exceed 100,000 transactions and hundreds of gigabytes of data transferred (egress) in one hour. All of those data points land in internal metrics accounts, and each account has a finite budget for how much data it can take in and process. Our previous emission strategy sent metrics to a single backing account. That worked for the metrics we already had but signals this large would eventually exhaust that account's quota. Scale wasn't an optimization we could add later. It was a prerequisite for launching these metrics at all. Sharding the metrics without splitting the view The answer to the capacity problem is to stop relying on one account. Instead, we shard our metrics across multiple internal metrics accounts. A shard is one slice of a larger system that holds part of the data and has its own capacity. Each shard has its own headroom, which we monitor and manage independently, so no single account caps growth. Geo-replication complicates this. A geo-replicated registry is served from many regions at once, and a single request can pass through more than one component: one answering API calls, another serving blob bytes, another delivering webhooks. However capacity is divided, every data point from every region and every component still has to be attributed to the registry it belongs to. Otherwise, you'd see your registry's activity in pieces and have to stitch it back together yourself. Activity from every geo-replication and component is attributed to its registry and counted once. Each registry's metrics land on one shard, different registries are spread across shards, and you still query one registry in the portal. When you open the Azure portal or query Azure Monitor, you query your registry. You never see or choose where that information is coming from. Counting each request once. Multi-hop requests raise the same question for accuracy. One blob pull can touch more than one component: the registry may answer with a redirect, and a different component serves the bytes. Each step is counted once, by the component that handled it: the redirect appears as its own Redirect transaction, the download as a Success transaction, and the bytes appear once in Data Transfer. Failed requests count as Transactions, so errors stay visible, but not as Data Transfer, because no bytes were delivered. Every emitting component uses the same ApiName and ResponseType vocabulary, and we verify that each counted request produces exactly one data point. Each step is counted once, by the component that handled it, and bytes count only when they're served. The result is one view of each registry, across every region and component, with each step of a request counted exactly once. What customers get Both metrics appear where you already look: Azure portal > your registry > Monitoring > Metrics, and through Azure Monitor for programmatic queries and alerts. Transactions counts registry API operations, with three dimensions: ApiName: the registry operation, such as manifest, tag, and blob operations, referrer and catalog listings, token requests, etc. ResponseType: Success, Redirect, ClientErrorUnauthorized, ClientErrorNotFound, Throttled, etc. Region: the geo-replication of the registry that served the request Data Transfer reports the total outbound data your registry transfers, in bytes, when it serves content such as blob and manifest downloads. You can split it by ApiName and Region. ApiName: the flow that moved the data, such as layer downloads, manifest downloads, image imports, replicating content to your geo-replicas, etc. Region: the geo-replication of the registry that served the request A typical investigation takes a few steps. Open Monitoring > Metrics, choose Transactions, and split by ResponseType to see successes, redirects, throttling, and errors at a glance. Switch the split to Region to see which geo-replication is serving the change. Then select New alert rule from the same chart. For example, filter to Throttled and alert when the total over 5 minutes exceeds a threshold you choose. To understand egress by region, chart Data Transfer over time and split it by Region to see how much data each geo-replication serves and whether that data transfer traffic is growing. Match the view to what you suspect: A deployment or metadata polling: split Transactions by ApiName to see whether blob and manifest reads or tag and listing calls are driving the change. A retry loop: filter ResponseType to Throttled, ClientErrorUnauthorized, or ServerErrorOther. A regional workload shift: split metric by Region. Larger image layers: compare the two metrics. Data Transfer rising while Transactions stays flat points to bigger artifacts, not more requests. Transactions split by ResponseType: successes, redirects, throttling, and errors at a glance. Built for the metrics that come next Transactions and Data Transfer run on the same sharded metrics path, and we built it so future metrics onboard onto that same path instead of competing for one account's capacity. The design scales with customer workloads and with the metrics we add next, without a redesign. Conclusion Transactions and Data Transfer give you a direct view of what your registry is doing: which operations it serves, whether they succeed, where they're served, and how much data moves. Sharding is how we delivered that view at scale without giving up accuracy, and it's the path future metrics will onboard onto. A few lessons generalize beyond metrics: Design for scale before you launch a high-throughput signal, not after. Attribute by resource, not by location. Activity spread across many regions still needs one source of truth per resource. Keep the complexity on the service side. Customers query a registry, not a shard, so how we manage capacity can evolve without changing what you query. Get started with Transactions and Data Transfer in Monitor Azure Container Registry and the supported metrics reference for Azure Container Registry.328Views4likes0CommentsAzure Verified Modules (AVM) is now owned by Azure engineering
Next community call: Monday 26th October 2026 @ 16:00 UK | 12:00 EDT | 09:00 PDT | 21:30 IST | 03:00 AEDT This call will be streamed to YouTube live so use the "Set reminder" / "Notify Me" options on YouTube and also put an entry in your calendar to remind you. This means it will automatically be recorded and published live once finished as well 👍 YouTube Live Link: aka.ms/AVM/CommunityCall ICS for your calendar: aka.ms/AVM/CommunityCall/ICS GitHub Issue Link: AVM Community Call - October 2026 · Issue #3079 · Azure/Azure-Verified-Modules - please add a comment for any topics or discussions you'd like covered Everyone is welcome whether you contribute to AVM or just use it. We want to welcome you for an insight into our roadmap over the next 6 months as well as an open discussion with you all. Azure Verified Modules (AVM) has moved into the Azure Deployments team, inside Microsoft’s Azure engineering organization. That is the headline, and it is a big one for us. AVM started as a community-led project inside Microsoft, built and maintained largely by people who cared about it alongside their day jobs in various roles and teams across Microsoft. It is now owned by an engineering team, with dedicated engineers working on it every day; as well as those who helped make AVM what it is today. I want to be clear about what that does and does not mean, because I know the questions this raises. AVM is still open source. The repositories, specifications, the contribution model and the way you consume modules from the public registries are all unchanged. What has changed is the level of investment behind it, and how sustainable we can make it. In short: Microsoft has increased its investment in AVM. It has moved from a community-led project into Azure engineering, with dedicated engineering resources behind it. It stays open-source. On the back of that, we are updating the support statement and introducing a three-tier module ownership model at the start of 2027 (more on these below). This blog post has a lot of content, please take the time to read it all but feel free to use the table of contents below to help you navigate it. If AVM is new to you AVM is the Microsoft standard for Infrastructure as Code (IaC) modules for Azure, in both Bicep and Terraform. Every module is built to the same published specification, passes the same continuous integration (CI) tests, and is published to the official public Bicep and Terraform registries. The idea is simple: you should not have to write the same Azure IaC code again, and you should be able to trust what you pick up. There is a lot more detail at aka.ms/AVM. And if you would rather watch than read, Jared Holgate and I covered AVM in our recent Azure Infra Summit session: watch the recording on YouTube. What the move lets us fix: our support statement Today, the AVM support statement includes day-based targets for responses and fixes. We have not met them consistently, and that does not give you clear or reliable expectations. We are removing those targets and aligning with the support model used by Azure CLI, Azure PowerShell, Bicep, AzAPI, and the AzureRM Terraform provider. The move into Azure engineering is the important part. Dedicated engineers will maintain modules directly and improve the tooling, automation, and framework used by all module owners. That is a stronger commitment than any fixed target we cannot reliably meet. It also lets us be clearer about who maintains each module. Right now, every AVM module is treated identically, and that is not sustainable. So, we are introducing module tiering. Introducing module tiering Right now, every AVM module is treated identically. That is not sustainable. A resource group module needs almost no attention. A storage account or virtual machine module needs constant work as the underlying service evolves. So, today we are introducing two tiers (and thinking about a third) based on who owns and maintains a module: Tier Owned by What it means Tier 1 (Core) The AVM engineering team Modules are owned directly by the AVM team inside Azure engineering. These are the ones we maintain as our day job alongside the AVM specifications and framework Tier 2 (Maintained) Any Microsoft employee (FTE) Modules are owned by any Microsoft full-time employee or team/s. It also includes other Azure engineering teams owning the modules for their own services. This is the model we have today, and it is not going away. Tier 3 (Open-Source) * being considered for future * Vetted external owners (future) An idea, not a commitment. It would let trusted external parties such as Microsoft MVPs and accredited partners own modules. We will not look at this until the 2nd half of calendar year 2027. One thing that will not change: the bar. Every module in every tier is built to the same AVM specification and passes the same CI checks. Tiering describes who is behind a module, not its quality. Ownership also stays aligned across languages if in Tier 1. If we own a module in Tier 1, we own it in both Bicep and Terraform. Why we are not publishing the module tiering list yet We want to know our real maintenance capacity before we commit. We are spending the rest of 2026 reducing toil and clearing the backlog. This work will show how many modules we can maintain. We would rather publish a list that we can sustain than change it soon after publication. Publishing a list will also focus attention on excluded modules. We want clear evidence before those discussions start. For context, our draft puts about 50 resource modules in Tier 1, across Bicep and Terraform. Current telemetry suggests these modules represent about 85 percent of AVM module deployments. Usage is one input. Critical services and other factors also matter. We will validate the draft before making a public commitment. Distributed ownership is still the point AVM has always run on decentralized ownership and moving into engineering does not change that. If anything, it should help. Being inside Azure engineering puts us much closer to the product teams who build the services, and getting more of those teams to own the modules for their own service has been a goal from day one. That is already happening. With the recent transition of Azure Landing Zones (ALZ), the Azure Migrate team now maintain the ALZ modules and the subscription vending modules in AVM. Those sit in Tier 2, but they are maintained by a dedicated engineering team. Tier 2 is not a lesser tier, it is a broader one. However, if they currently own a resource module that will be included in Tier 1, they are still welcome to be involved in its ownership alongside the AVM engineering team, but we would also encourage them to own a module outside of Tier 1 so we have an owner on as many modules as possible. But all of this will be dealt with when we implement the tiering structure in early 2027. Tier 2 ownership remains open to Microsoft employees and teams. The AVM engineering team will support those owners through improved tooling, automation, and the AVM framework. We will confirm ownership changes when we implement module tiering in early 2027. Come and meet the team (AVM Community Call) Rather than list names on a page, we would rather you meet the people. Join our next AVM community call, where the new engineering team looking after AVM will introduce themselves and take your questions. If you want to know who is behind AVM now, or discuss anything in this post, this will be the place to do it, and we can’t wait to see you all there! Next community call: Monday 26th October 2026 @ 16:00 UK | 12:00 EDT | 09:00 PDT | 21:30 IST | 03:00 AEDT This call will be streamed to YouTube live so use the "Set reminder" / "Notify Me" options on YouTube and also put an entry in your calendar to remind you. This means it will automatically be recorded and published live once finished as well 👍 YouTube Live Link: aka.ms/AVM/CommunityCall ICS for your calendar: aka.ms/AVM/CommunityCall/ICS GitHub Issue Link: AVM Community Call - October 2026 · Issue #3079 · Azure/Azure-Verified-Modules - please add a comment for any topics or discussions you'd like covered Everyone is welcome whether you contribute to AVM or just use it. We want to welcome you for an insight into our roadmap over the next 6 months as well as an open discussion with you all. What happens next We update the published module support statement and remove the day-based response targets. The team keeps burning down issues and pull requests and keeps reducing the manual toil in our CI. We validate our maintenance run rate through the end of calendar year 2026. We publish the initial tier classifications once we can stand behind them. We revisit Tier 3, including the legal and intellectual property questions, in 2027. AVM got here because customers, partners and contributors backed it and used it in anger. That has not changed, and neither has our need for your input. If you think we are getting this wrong, tell us in GitHub Discussions. Candidly, the feedback we get on this will shape how we land it. And finally, thank you to everyone who built this AVM exists because many people put real work into it, often alongside their day jobs. Matt White, Charlie Grabiaud, Mate Barabas, Pankaj Meshram, were some of AVM’s key founders and helped shape the project during its early days that are no longer involved in AVM day-to-day. Jared Holgate, Alexander Sehr, Erika Gressi, Kris Baranek, Sebastian Graf, Rene Hezser and Chris Sidebotham remain involved today helping develop and maintain the AVM framework and specifications with the engineering team. Some contributors have moved to other roles, teams, or companies. Many continue through issues, pull requests, community calls, and module ownership and contributions. Every contribution helped AVM reach this point and continue to drive it forward today. The move into Azure engineering adds dedicated investment. It does not replace the community that built and sustained AVM. To every past and present contributor and module owner: thank you for your time, commitment, and belief in AVM. Thanks, Jack and the AVM team.2.4KViews3likes0CommentsEnhanced Feature Flags: A New Foundation for Feature Management in Azure App Configuration
Shipping is no longer just about deploying code. Consider a team introducing a new checkout experience. The code is already in production, but the team wants to expose it to a small audience, gradually increase availability, monitor the results, and retain the ability to turn it off if something goes wrong. Feature flags make that possible without requiring another deployment. As feature flags become increasingly central to how software is released and operated, we saw an opportunity to evolve how they’re represented in Azure App Configuration. Enhanced Feature Flags are available in public preview, with a dedicated resource model designed specifically for feature management. Why rethink the feature flag resource model? Consider a team preparing to launch a new check out experience. The release manager needs to control when the feature becomes available but shouldn’t necessarily have permission to modify payment settings or other application configuration. With traditional feature flags sharing the same key-value resource and permission model as application configuration, separating these responsibilities isn’t possible. Similarly existing SDKS and tooling simplify feature flag management; the underlying APIs still treat flags as specially formatted configuration entries rather than resources with their own defined structure. These are not challenges with feature evaluation itself. They're challenges with how feature flags are represented, managed, and governed. Enhanced Feature Flags address this by introducing a purpose-built resource model, with dedicated APIs and separate access control. What changes with Enhanced Feature Flags? The new model introduces several important improvements. 1. Feature management gets its own security boundary Feature flags often change application behavior in production, and the people responsible for those changes may not be the same people responsible for application configuration. With Enhanced Feature Flags, organizations can grant access to feature flag resources independently of configuration key-values. A team responsible for feature rollout, for example, can manage flags without also receiving permission to modify unrelated application settings. This creates a clearer security boundary for applying least privilege access to feature management. 2. Feature flags get a dedicated API surface Previously, managing feature flags through configuration APIs required clients and automation to understand specific naming conventions, content types, and serialized feature definitions. Enhanced Feature Flags expose dedicated APIs for creating, querying, updating, and deleting flags. The benefit isn't simply another API. Tools and deployment workflows can now work directly with a resource designed for feature management instead of interpreting a feature flag stored as configuration. 3. Validation moves closer to the source Enhanced Feature Flags have a defined resource schema that Azure App Configuration can validate when a flag is created or updated. Malformed definitions can be rejected before they are stored, providing consistent validation across clients and tooling. Existing feature management capabilities continue to work Enhanced Feature Flags build on the feature management capabilities already available in Azure App Configuration, including targeting, variants, allocation, and telemetry. Applications can continue using their existing feature evaluation logic with supported versions of the App Configuration provider libraries. And importantly, existing key-value-based feature flags remain supported. Teams can evaluate the new model alongside their current flags, rather than treating this preview as a mandatory migration. See Enhanced Feature Flags in action Watch this short demo to learn how granular role-based access control enables teams to manage feature releases independently while keeping application configuration protected. A foundation for what comes next Enhanced Feature Flags solve concrete management and governance challenges today, but the opportunity goes further. Giving feature flags their own resource model creates room for feature management to evolve independently from general application configuration, with deeper investments in areas such as automation, governance, targeting, and connecting feature delivery to application outcomes. The longer-term opportunity is to make managing a feature throughout its lifecycle as natural as developing and deploying it. Enhanced Feature Flags are available now in public preview in Azure App Configuration. If you're building a new application or evolving your feature management workflows, explore the new resource model and let us know what you think. We want Enhanced Feature Flags to provide the foundation for the next generation of feature management in Azure App Configuration, and your feedback will help shape where we take it next. Learn about Enhanced Feature Flags Explore the Enhanced Feature Flags REST API Share feedback with the Azure App Configuration team #Azure #AzureAppConfiguration #FeatureFlags #FeatureManagement #DeveloperExperience327Views2likes0CommentsData Transfer and Transactions metrics now generally available for Azure Container Registry
Azure Container Registry now provides two new platform metrics that make it easier to understand outbound data transfer, inspect API traffic, and investigate throttled or failed requests without first opening a support request. We're excited to share the general availability of the Data Transfer and Transactions metrics for Azure Container Registry (ACR). Both metrics are emitted automatically through Azure Monitor and include dimensions that help you move from “something changed” to the operation, response, and region that explain the change. Available to all ACR customers today: The Data Transfer and Transactions metrics are available automatically for every registry, with no additional configuration or cost for the metrics themselves. Deeper visibility into registry activity ACR's existing platform metrics provide useful high-level signals such as total and successful pull and push counts, along with storage usage. However, those aggregate signals don't tell you which API operation changed, which region served the traffic, or whether requests were successful, rejected, or throttled. Answering those questions often required you to configure diagnostic settings, query logs, correlate client-side telemetry, or contact support. The new metrics add built-in dimensions for common operational investigations, so you can identify the traffic pattern first and then decide whether to tune clients, adjust deployment behavior, change capacity, or investigate a failure. Before What the new metrics unlock Aggregate pull and push counts Transaction volume split by registry API operation. HTTP 429 responses visible primarily from client failures Throttled transactions filtered by response type and split by API or region. Limited attribution for outbound transfer Outbound bytes split by operation and serving registry region. Separate log and client-side investigations Built-in metric charts, alerts, and Grafana dashboards without custom instrumentation. This visibility is especially useful for shared registries and geo-replicated environments. If request volume increases, outbound transfer changes, or clients begin receiving HTTP 429 responses, you can investigate the activity directly in Azure Monitor or the integrated Grafana experience. What is new Data Transfer: understand outbound registry traffic The Data Transfer metric measures total outbound data transferred from your registry in bytes. Split the metric by ApiName to distinguish client blob and manifest downloads, geo-replication traffic, and data read when another registry imports content from this registry. Split by Region to see where that transfer originated. Transactions: understand registry API activity The Transactions metric counts registry API operations. Use its dimensions to identify which operations are generating traffic, where requests are served, and whether the response succeeded, redirected, failed, or was throttled. Dimension Available on What it tells you ApiName DataTransfer/Transactions The registry operation represented by the metric. Region DataTransfer/Transactions The region that served the request or from which data was transferred. ResponseType Transactions The request outcome, including success, redirect, authorization failure, not found, throttled, and other client or server errors. For the complete list of API names and response classifications, see the Azure Container Registry monitoring data reference . Questions you can answer Which APIs are busiest? Split Transactions metric by ApiName to compare manifest, layer, metadata, and authentication operations. How is traffic distributed across my registry geo-replications? Split Transactions and DataTransfer metrics by Region to monitor transaction volume and outbound data transfer across the registry's geo-replications. Are my requests being throttled? Filter Transactions by ResponseType = Throttled, then split by ApiName or Region to find the affected traffic. What operations are driving outbound data transfer from my registry? Split DataTransfer by ApiName to compare client downloads, replication, and import-source traffic. You can explore these new insights in two ways. Start with the integrated Grafana dashboard for a curated, customizable view of registry health and activity. For quick questions or focused investigations, use Azure Monitor Metrics to filter and split the underlying metrics by API, region, and response type. Start with the integrated Grafana dashboard Alongside these metrics, we're introducing a new visualization experience for ACR customers: Dashboards with Grafana. The experience is enabled by Azure Managed Grafana and brings a prebuilt, customizable Grafana dashboard into the registry's Azure portal experience. The dashboard provides out-of-the-box panels for key operational insights, including transaction activity and request outcomes by region, outbound data transfer, throttled requests, and storage consumption. To get started, open your registry in the Azure portal and select Monitoring > Dashboards with Grafana. The gallery includes the Azure Container Registry observability dashboard with views for data transfer, transaction trends, throttling, and storage consumption. You don't need to deploy or manage a separate Grafana instance. For teams that already use Grafana, the ACR Observability dashboard is also available in the public Grafana dashboard gallery, where it can be imported and customized for existing monitoring environments. Use the prebuilt dashboard as a starting point, then add panels and customize the views to surface and save the insights most important to your team. You can also use Grafana Explore for ad hoc analysis. The integrated observability dashboard brings key registry metrics together in one view. The dashboard is broken down into sections: Overview, Data Transfer, Transactions, and Storage. Explore the dashboard sections, including Transactions, to view overall request breakdown and audit throttle activity. For dashboard creation, customization, access, and deployment guidance, see Use Grafana dashboards in Azure Container Registry. Run ad hoc metric queries in Azure Monitor For a quick question or focused investigation, open your registry and select Monitoring > Metrics. Select Data Transfer or Transactions, then use filtering and splitting to analyze the relevant API, region, or response dimensions. Investigating throttling? Start with Transactions, filter ResponseType to Throttled, and split by ApiName. After you identify the traffic pattern, review the mitigation guidance in Azure Container Registry SKU features and limits . Use the Transactions dimensions to investigate operation volume, regional traffic, and outcomes. Use Data Transfer dimensions to identify the operations and regions generating outbound transfer. Learn more Monitor Azure Container Registry Azure Container Registry monitoring data reference Use Grafana dashboards in Azure Container Registry Azure Container Registry API request rate limits Engineering deep dives For a closer look behind the scenes, these engineering deep dives explain how our team designed and implemented the capabilities that make these new insights possible. Making ACR Data Transfer Visible: The Storage Activity Platform Behind GetBlob Metrics Making Registry Activity Visible at Scale Start exploring the metrics today Open your registry in the Azure portal and select Monitoring > Dashboards with Grafana to explore transaction trends, outbound data transfer, throttling, and storage in one integrated view. Use the built-in dashboard as a starting point, then add panels and customize the views to surface and save the insights most important to your team. This integrated experience gives registry teams a self-service path from signal to explanation, helping you understand usage patterns and investigate failed or throttled requests before turning to logs or opening a support request.364Views4likes1CommentBeyond One-Size-Fits-All: Decision Routing for GitHub Copilot in CLI & VS Code
As developer tools move into the age of agentic AI, it is easy to fall into a familiar habit: when a task matters, choose the strongest—and usually most expensive—model available. Real software work is more varied than that. Explaining a function, editing a README, adding a boundary test, debugging a cross-module race condition and reviewing authentication logic demand very different levels of reasoning, context, tool use and reliability. A fixed model for every turn either wastes latency and budget or leaves difficult tasks underpowered. That is the motivation behind decision-ghc-router: GitHub Copilot continues to execute, while a Decision Router selects a sufficiently reliable and economically sensible model at the start of each new user turn. (The design also draws on gargpratyush/jev-router, especially its per-turn routing, native CLI preservation and model pinning across tool continuations.) The goal is not to build another agent outside Copilot or replace the native developer experience with a custom chat UI. GitHub Copilot CLI and the VS Code GitHub Copilot extension should keep their existing authentication, model catalog, tools, permissions, sessions and streaming behavior. The router adds one short, explicit decision step—and then gets out of the way. 1. Start with the distinction: a Decision Model is not a Model Router Before discussing implementation, two frequently conflated concepts need to be separated. A Decision Model makes bounded, structured judgments A Decision Model is not prompted with “write an article.” It receives: a current state, expressed as text or JSON; one or more bounded questions; explicit options or grading criteria. It returns typed results and probabilities that software can act on immediately, rather than free-form prose. For example: noul: Does this tool call touch production data? Return a probability between 0 and 1. choice: Should this task use the Fast, Balanced or Strong tier? Return the selected option and a probability for every option. score: How risky is this code change? Return an ordered score and its probability distribution. A Decision Model is therefore a fast, calibratable judgment primitive. Its uses extend beyond model selection to classification, ranking, prioritization, validation, agent control, safety screening and AI judging. A Model Router turns judgment into execution A Model Router is a system pattern, not a single model. A production-ready router must typically: discover models actually available to the signed-in account; reject candidates that are unavailable, unpriced, context-insufficient or API-incompatible; build a minimal routing state; invoke a scorer—which might be rules, a benchmark table, an LLM classifier or a Decision Model; apply confidence, cost, latency, safety and organizational policy; select a concrete model and start native execution; pin that model across tool continuations; emit decisions, estimates and failures for audit and tuning. In short: The Decision Model judges what is most suitable. The Model Router makes that judgment usable, compliant, executable, observable and recoverable. A Decision Router does not replace the larger routing system. It gives that system a specialized, fast and threshold-friendly scoring engine. Decision Model versus Model Router Dimension Decision Model Model Router Nature Specialized model capability Application or platform architecture pattern Input State, bounded questions, options or grading criteria User task, account catalog, prices, context limits and policy Output Typed answer and probabilities Concrete model, execution path, policy outcome and telemetry Content generation Does not produce free-form content Usually dispatches a generative model Account entitlement Not responsible Responsible API compatibility Not responsible Responsible Failure handling Provides uncertainty Must define fallback or stop behavior Broader use Classification, scoring, routing and validation Multi-model orchestration, cost governance and runtime control 2. Microsoft-Decision-1: why it fits developer-tool routing Microsoft introduced Microsoft-Decision-1 in October 2026 as a specialized model for fast decision scoring, available through Microsoft Foundry. Unlike a generative LLM, it does not produce an essay or a written chain of reasoning. It makes a focused judgment about text or JSON and returns typed numerical decisions. Microsoft describes the model as a post-trained Qwen3.5-9B designed for single-pass scoring over fixed options. It reports the highest accuracy in a 36-benchmark comparison spanning nearly 150,000 questions kept blind from training, P50 latency roughly 35 times faster than GPT-6 Sol, and an average 1.3% decision-flip rate across eight perturbation types. At launch, Microsoft listed input at US$0.042 per million tokens with no output-token charge; pricing is dynamic, so a deployment should use the current Microsoft Foundry listing. Those are Microsoft-published benchmark results, not a substitute for evaluation on a team’s own development workload. Microsoft-Decision-1 exposes three question types that map naturally to an AI control plane: noul for binary gates such as “May this command run automatically?” choice for bounded routing such as “Which model tier should handle this turn?” score for ordered grading such as “How severe is the change risk?” Why not use a small LLM classifier? That is a valid architecture. Many model routers ask a lightweight LLM to emit easy, medium or hard. GitHub Agentic Workflows’ experimental model routing also classifies a task before ranking allowed model-and-effort combinations through precompiled routing tables. A dedicated Decision Model, however, offers four useful properties for developer tools: Bounded output. A router needs a label and probabilities, not persuasive prose. Predictable latency. Agent workflows amplify the cost of every sequential control-plane call. Policy-ready confidence. If the top probability is below 0.65, a local policy can avoid downgrading, keep the current model or request manual selection. Composable governance. One structured request can score model tier, operational risk and the need for human review. A conceptual choice request for Copilot routing The following is simplified pseudodata—not repository source—and omits deployment and authentication details: { "state": { "task": "Fix intermittent failures in the authentication integration tests", "estimatedContextTokens": 18000, "toolUseExpected": true, "workspaceScope": "multi-file", "latencyPreference": "balanced" }, "questions": { "model_tier": { "type": "choice", "instructions": "Choose the least expensive tier likely to complete the task reliably in one pass.", "criteria": { "fast": "Simple explanation, formatting, lookup, or small deterministic edit", "balanced": "Normal coding, tests, debugging, or limited multi-file work", "strong": "Ambiguous architecture, security, difficult debugging, or broad multi-file reasoning" } } } } The response identifies a tier and assigns a probability to every tier. The router then maps the abstract choice to a concrete model that is truly available to the current GitHub account. That separation matters: a Decision Model should not assume that a user owns or can access a particular model. The account catalog is the source of truth. 3. The decision-ghc-router scenario and reference architecture The architecture has two hosts but one consistent decision model. 3.1 GitHub Copilot CLI: put the router in native /model In the public predecessor implementation, a user-level extension adds a router entry to GitHub Copilot CLI’s native /model menu. The user can select the router or choose a concrete model directly: Select Decision Router: route every new user turn. Select a concrete model: bypass routing and return to native fixed-model behavior. Continue a tool call: keep the model chosen for that turn; do not classify again. Explicitly request a model: the explicit request should win. The CLI path uses a random-port 127.0.0.1 proxy to expose the router as a temporary provider while preserving Copilot authentication, sessions, tools, permissions and streaming. GitHub credentials should remain in memory and be used only for HTTPS requests to GitHub. The local proxy uses separate random credentials; GitHub credentials must not be written to logs or sent to the Decision API. This is the design principle I care about most: The router changes which model is selected, not how Copilot works. 3.2 VS Code and VS Code Insiders: enter the Chat Model Picker The editor integration is a separate extension. It registers decision-router in VS Code Chat’s model picker and uses the public Language Model API to discover Copilot models available to the account signed into that editor. The privacy boundary is intentional: The Decision Model receives an unambiguously extracted task or a routing-only summary entered by the user. If the task cannot be reliably isolated from editor context, the extension should not automatically upload attachments, source files or the full conversation. The selected Copilot model still receives the full conversation, tool definitions and workspace context. VS Code invokes native tools, while tool-call IDs maintain model consistency. The short version is: minimize data for decision; maximize context for execution. 3.3 The seven-step loop for each new user turn Receive the task through native Copilot CLI or VS Code Chat. Discover candidates from account models, prices, context capabilities and API compatibility. Build routing state with the minimum sufficient task summary and bounded choices. Call Microsoft-Decision-1 and receive choice probabilities. Apply local policy for confidence, cost, compatibility and manual overrides. Execute natively with the selected model, existing tools, permissions, session and streaming. Pin and trace the model for tool continuations while recording the decision and estimate. 3.4 Why not reroute every tool continuation? Imagine a model runs tests, reads the failure output and then edits code. If the router chooses a new model after every tool result: prompt-cache benefits may disappear, increasing total cost; the new model may interpret earlier tool calls differently; the debugging chain becomes harder to reproduce and audit. I therefore retain one of jev-router’s strongest ideas: make one decision at the start of a new user turn, then pin that model for the resulting tool chain. Main conversations and sub-agents should be pinned independently. 4. Main technologies and frameworks Based on mechanisms verifiable in the public predecessor and the Microsoft-Decision-1 evolution described here, the project separates into the following layers. Node.js and ESM modules The core router uses Node.js and .mjs modules to handle: CLI startup and argument forwarding; model catalog and price adaptation; the local HTTP proxy; configuration and environment variables; Decision API calls; policy, errors and telemetry. The public predecessor requires Node.js 22.16 or later and uses Microsoft’s npm package source for relevant dependencies. GitHub Copilot CLI extension interfaces The CLI integration relies on experimental extension interfaces to register the router as a native model entry. It explicitly enables the provider-endpoint interface and obtains the model catalog, runtime inference endpoint and authentication from the active session. Three rules are essential: Do not modify the user’s global default model. Do not automatically grant shell or other tool permissions. If initialization fails, report a clear error instead of pretending routing succeeded. Local loopback proxy The loopback proxy is the adapter that preserves the native CLI: listen only on 127.0.0.1; use a random port and random local credentials; map the router’s selection to a real Copilot execution model; preserve streaming, tool calls, sessions and permission prompts; never create a second hidden agent loop. VS Code Extension API The editor extension discovers current candidates through: vscode.lm.selectChatModels({ vendor: "copilot" }) and is packaged as a VSIX. The CLI and editor are independent hosts and may use different GitHub accounts with different entitlements. Candidate discovery must therefore be host-specific, session-specific and dynamic—not a hardcoded list of model IDs. Microsoft Foundry and the Decision API Microsoft-Decision-1 can be deployed in Microsoft Foundry through GlobalStandard or, in selected regions, DataZoneStandard. Authentication can use Microsoft Entra ID (recommended) or an API key. In this architecture, the Decision API only scores choices: Input: minimal task state, bounded candidates and explicit criteria. Output: selected option, option probabilities and usage. Not its responsibility: GitHub credentials, developer tools, full workspace access or code execution. That separation makes the decision plane and execution plane independently governable. Model catalog, pricing and capability adapters The public predecessor discovers models from the signed-in account instead of hardcoding them. Before scoring, a router should exclude: auto, hidden, disabled or unconfigured entries; models without usable price information; candidates with insufficient input context; models incompatible with the host’s wire API; models restricted by administrator policy. Cost estimation supports ranking and user feedback; it is not a final bill. Promotions, cache discounts, hidden context, retries and later tool rounds all affect the result. GitHub Billing remains authoritative. 5. What I borrow from jev-router—and what changes The value of gargpratyush/jev-router is not merely “use a small model for easy tasks.” It embeds routing into familiar CLIs without taking away their native behavior. The ideas I retain include: one routing decision per new user turn; a router sentinel in the native model picker; concrete-model selection pauses routing; abstract Fast, Balanced, Strong and Long tiers map to host-specific models; tool continuations keep the tier selected at the start of the turn; explicit model requests win; low confidence should not trigger an aggressive downgrade; large conversations must account for cache and migration cost; explanation data should show why a tier was selected. The decision-ghc-router evolution replaces the external JEV/System One scorer with Microsoft-Decision-1 and emphasizes five changes: Probability is a first-class signal. Policy can threshold the decision instead of accepting a label blindly. Bounded choices come from the real catalog. Decision-1 only chooses among already eligible candidates. Local policy owns the final answer. Organizational rules, compatibility and manual overrides remain deterministic. The Decision Model is reusable. A single structured call can also score operational risk and the need for human review. Local and cloud responsibilities are explicit. Cloud scoring is isolated from credentials and execution. 6. Representative use cases A. Fast explanation and small edits “Explain this regular expression,” “turn this note into a table,” or “add a null-value test to an existing function.” The router can often select the Fast tier. The objective is not the weakest model; it is the least expensive model likely to complete the task reliably in one pass. B. Normal development and debugging “Fix the failing test,” “refactor this module without changing its API,” or “use the stack trace to locate the bug.” These tasks require code reading, tool use and moderate reasoning, so they often land in Balanced. C. Security, architecture and broad multi-file reasoning “Review this OAuth callback for state confusion,” “design cross-region failover,” or “find a race condition across services.” The router should choose Strong even when it costs more. Routing optimization means “economical subject to reliable completion,” not “always cheaper.” D. Long context and large repositories If a candidate cannot hold the estimated input, it must be removed before scoring. For an already large conversation, the router should also avoid downgrading when lost cache work or context migration would cost more than the model-price saving. E. Organizational policy and risk gates The same Decision API request can include additional noul or score questions: Does the task involve production data? Is the proposed command destructive? What is the security risk level of the change? Should execution be handed to a human reviewer? At that point the router grows from a cost optimizer into a lightweight control plane for agents. 7. Policies I would keep for production Filter deterministically before scoring Entitlement, API compatibility, context limits and administrator restrictions are facts. The Decision Model should not be asked to guess them. Do not automatically downgrade on low confidence When the top probability falls below a calibrated threshold, the router can: keep the current model; cap automatic movement at Balanced; request manual selection; send high-risk tasks to Strong or human review. The threshold must be calibrated on labeled tasks from the target environment, not copied from an example. Explicit intent beats automatic routing If the user says “use the Strong model” or selects a concrete entry in the picker, the router should step aside immediately. Never substitute silently Missing credentials, Decision API timeouts, unknown pricing and insufficient context should produce an explicit state. Whether to fail open, fail closed or keep the current model must be an intentional host or organizational policy. Record decisions without logging every prompt by default Useful telemetry includes: anonymized session and turn IDs; candidates and exclusion reasons; selected tier, probabilities and policy overrides; estimated input/output and one-turn cost; completion, retry and manual-reselection outcomes. Full prompts, source code and tool results should be excluded by default or governed by explicit retention and data-handling policy. Evaluate the router on task success, not the cheapest request Better metrics include: first-pass completion rate; total time to completion; total cost including retries and tool rounds; manual model-change rate; low-confidence and misrouting rates; safety and policy violations. 8. Why this matters beyond one repository From a developer-advocacy perspective, the Decision Router is not simply a token-saving utility. It illustrates a clearer division of responsibilities in agent engineering: Generative models understand, reason, write code and call tools. Decision Models make fast, structured and probabilistic judgments. Routers and policy engines place those judgments inside real account, budget, compatibility and governance constraints. Developer-tool hosts retain identity, permission, context and execution control. Future AI developer tools will not be tied to one “default large model.” They will manage a portfolio of models with different speed, cost, context and capability profiles. The differentiator will no longer be merely which model a product connects to, but: Can it select the right model at the right moment, in an explainable and governable way, without breaking the developer experience? That is why I am adding a Decision Router to GitHub Copilot CLI and the VS Code GitHub Copilot extension. GitHub Copilot keeps executing. Microsoft-Decision-1 makes the fast judgment. The local router turns that judgment into a usable engineering decision. References decision-ghc-router jev-ghc-router gargpratyush/jev-router Microsoft-Decision-1: Our model for fast decision-making Deploy and use Microsoft-Decision-1 in Microsoft Foundry GitHub Agentic Workflows — Model Routing GitHub Copilot model billing and pricing522Views0likes0CommentsIntroducing Azure Container Apps Sandboxes: Secure Infrastructure for Agentic Workloads
Today we are announcing the public preview of Azure Container Apps Sandboxes - a new first-class resource type that gives you fast, secure, ephemeral compute environments with built-in suspend and resume. This is the underlying infrastructure on which products like Cloud sandboxes in GitHub Copilot, Foundry Hosted Agents, and Azure Container Apps Express are built, you now have the opportunity to build your solutions leveraging this infrastructure. Azure Container Apps Sandboxes unlocks two massive opportunities. For platform developers and ISVs, sandboxes give you the same isolated compute fabric that powers many Microsoft products. You get the building blocks to create your own multi-tenant platform on proven, enterprise-scale infrastructure. For AI agents, sandboxes become a self-configurable tool that lets agents extend their own capabilities on the fly. An agent can spin up a fresh sandbox in milliseconds and use it to execute untrusted code, compile source, test HTTP requests against a live app, launch a browser session, or tackle whatever needs a quick and scalable infrastructure. On one side it empowers humans to build platforms, on the other it empowers agents to build their own capabilities. Both get enterprise-grade isolation, instant startup, and snapshot-based persistence out of the box. We'll walk through the resource model, sandbox lifecycle, the features that set Sandboxes apart - like snapshots, lifecycle policies, network egress controls, volumes, and managed identities - and show you how to get started with the portal and CLI. What Are Container Apps Sandboxes? Container Apps Sandboxes are secure, isolated compute environments that start in sub-second time, scale to thousands, and cost nothing when idle. Each sandbox runs in its own hardware-isolated microVM boundary - fully separated from the host, the platform, and every other sandbox. You bring your own Open Container Initiative (OCI) image, and Sandboxes handle the rest: provisioning from prewarmed pools, strong multi-tenant isolation, and snapshot-based suspend/resume that preserves full memory and disk state across sessions. There are many ways Sandboxes can help you build your next project - here are a few: Your own build & test systems - wire a Sandbox into your CI/CD flow to run builds while your laptop stays cool. Agents that can run anything safely - an agent spawns a sandbox, executes work inside it, and returns the output with no agent host privileges required. Agent swarms - decompose a research question, spawn N sandbox workers in parallel (each pinned to its own image and egress policy), and synthesize the result. Early access customers are already unlocking significant benefits by leveraging Azure Container Apps Sandboxes. "With Azure Container Apps sandboxes, SitecoreAI can safely enable agents to take real action. The combination of multi-tenant isolation, rapid scale-out, and full automation allows Sitecore to run long-lived, autonomous agents that securely execute code, manage workflows, and interact with enterprise systems within secure, governed environments. With this foundation, we can build agents that do real work: assembling content, personalizing experiences, and optimizing campaigns in production. Agents that operate continuously, learn from results, and improve over time, so our customers get better outcomes without giving up control." - Mo Cherif, VP of AI and Innovation, Sitecore "We got early access to Azure Container Apps Sandboxes, and got the first prototype integrated with Atlas AI in hours, and it's already shaping a new Atlas AI capability that we plan to launch in preview in Q3. It gives every Atlas AI agent a safe, sandboxed workspace (file system, terminal, code execution) on a customer's live data in Cognite Data Fusion. The value: Industrial process, reliability, and production engineers spend days and weeks on questions like "which wells are underperforming and why?" These questions are tractable but expensive, so they are asked rarely and decisions are made on gut feel. With this, an agent pulls the data, runs the analysis, cross-references maintenance and inspection records, and returns a cited draft in minutes. Sandboxes make it practical: Aligned feature set, per-customer isolation, pause/resume across multi-day investigations, scale-to-zero economics." - Kelvin Sundli, Product manager, Atlas AI, Cognite Resource Model: Sandbox Groups and Sandboxes The top-level ARM resource is Microsoft.App/SandboxGroups. A Sandbox Group is the management boundary for a collection of sandboxes that share configuration - think of it like a Container Apps Environment, but purpose-built for sandboxes. When you create a Sandbox Group, you specify: Subscription, Resource Group, and Region Sandbox defaults (optional): default CPU, memory, disk, max sandbox count, and default idle timeout Networking: optionally deploy into a custom VNet with a dedicated subnet for private networking Identity: System or user assigned Entra identity. Individual sandboxes are created within a Sandbox Group. Each sandbox has its own source (disk image or snapshot), resource tier, lifecycle policy, network egress policy, environment variables, ports, volumes, and connections. Sandbox Lifecycle Sandboxes have a well-defined lifecycle with the following states: State Description Creating Provisioning the sandbox from a disk image or snapshot Running Actively executing - backed by a live microVM Idle System-suspended after inactivity; can auto-resume on the next request Suspended Full state (memory + disk) preserved as a snapshot; no compute costs Resuming Restoring from a suspended or idle state - sub-second for most workloads Stopped User-initiated stop; can be resumed Stopping Graceful shutdown in progress Deleting Teardown in progress The key insight here is the distinction between Idle and Suspended. When a sandbox goes idle (e.g., no traffic for a configured timeout), the system can automatically suspend it and capture a snapshot. When a new request arrives, the sandbox resumes transparently. This gives you scale-to-zero economics with stateful compute - something that wasn't possible before without significant custom engineering. Disk Images: Bring Your Own Container Sandboxes boot from Disk Images - Open Container Initiative (OCI) images converted into an optimized root filesystem format. You point to any OCI image (public or private registry), and the platform builds a bootable disk image from it. You can start with public, pre-built images maintained by the platform (for example, Ubuntu base images), or bring your own private images. For private registries, you can authenticate with username/token or use a user-assigned managed identity for Azure Container Registry (ACR) – integrated with Azure as you expect. Snapshots: Full-State Persistence Snapshots capture the complete state of a running sandbox - memory, disk, and all running processes. When you resume a sandbox from a snapshot, every process, open file handle, and in-memory data structure is restored exactly as it was. A snapshot captures the full state of a running sandbox: memory pages, disk, processes. Two ways to make one - automatically on suspend, or manually on demand. Three things they're great for: Checkpointing mid-task so a long-running agent can resume exactly where it left off Cloning an environment that's already warm - dependencies installed, caches populated, services running Shipping a "ready-to-go" state that resumes in sub-second instead of cold-booting Snapshots are free during the preview, after which they will be stored as Azure Blob Storage at standard rates. Each snapshot records the source sandbox, resource allocation (CPU, memory, disk), and container metadata - so what you get back is exactly what you snapshotted. Resource Tiers Every sandbox is assigned to a resource tier that determines its CPU, memory, and disk allocation: Tier CPU Memory Disk XS 0.25 vCPU 0.5 GiB 5 GiB S 0.5 vCPU 1 GiB 10 GiB M (default) 1vCPU 2 GiB 20 GiB L 2 vCPU 4 GiB 40 GiB XL 4 vCPU 8 GiB 80 GiB When creating a sandbox from a snapshot, the resource tier is inherited from the snapshot and cannot be changed - this ensures the restored environment has the exact resources it was running with when the snapshot was taken. Lifecycle Policies: Auto-Suspend and Auto-Delete Every sandbox can be configured with lifecycle policies that automate state transitions and cleanup: Auto-Suspend Idle timeout: How long a sandbox can sit idle before being suspended (configurable: 1m, 2m, 5m, 10m, 30m, 60m) Suspend mode: Disk + Memory (default): Full snapshot including memory state - resume picks up exactly where you left off, with all processes and in-memory data intact. Disk: Only the disk is preserved; the VM restarts fresh on resume. Useful when you only need file persistence, not process continuity. Auto-Delete Automatically delete sandboxes after a configurable number of days of inactivity Prevents accumulation of abandoned sandboxes that consume snapshot storage These lifecycle policies are what make Sandboxes economically viable at scale. A platform serving thousands of tenants can configure aggressive idle timeouts (say, 60 seconds) with Memory suspend mode, and each tenant's sandbox disappears from the billing meter almost immediately - but resumes in sub-second time the moment they return. Network Egress Policy For scenarios involving untrusted code - AI agents executing LLM-generated scripts, multi-tenant SaaS with user-submitted workloads - controlling outbound network access is critical. Sandboxes provide a per-sandbox Network Egress Policy: Default action: Allow or Deny all outbound traffic Host rules: Domain-pattern rules (e.g., *.github.com → Allow) to permit specific destinations Custom CIDR rules: Network-level rules for IP ranges (e.g., 10.0.0.0/8 → Deny) Skip egress proxy: Option to bypass the egress proxy entirely when custom VNet routing handles policy enforcement This means you can run a sandbox in a deny-by-default posture and allowlist only the specific endpoints it needs (your API server, a package registry, etc.) - without setting up NSGs or firewall appliances. Managed Volumes: Persistent and Shared Storage Sandboxes support two types of mountable volumes, both managed by Microsoft: Volume Type Backed By Best For Managed Azure Blob Azure Blob Storage Shared data across sandboxes, file uploads/downloads, persistent artifacts Managed Data Disk Azure Disk Storage High-performance storage for databases, build caches, large working sets - only available to one sandbox at a time Blob volumes come with a built-in file explorer in the portal - you can browse, upload, download, create folders, and drag-and-drop files directly. Data Disk volumes provide dedicated block storage with configurable sizes. Secrets and Identity Secrets Sandbox Groups support key-value secrets scoped to the group. Secrets can be created, edited, and referenced by sandboxes within the group. These secrets can be used in egress policies to modify requests with transform or header-injection rules, without exposing the secrets to code running inside the sandbox. Managed Identity Sandbox Groups support both system-assigned and user-assigned managed identities, with full RBAC role assignment management. This means your sandboxes can authenticate to Azure services (Key Vault, Storage, Cosmos DB, etc.) without managing credentials - the same identity model you use everywhere else in Azure. MCP Connectors and Triggers ACA Sandboxes now supports managed connectors through the Model Context Protocol (MCP), giving sandboxes access to external APIs - including Microsoft 365, Salesforce, ServiceNow, GitHub, and 1,400+ other systems - without managing credentials directly. Attach a Connector Gateway to your sandbox group, and every sandbox in the group can call external APIs through a standardized MCP interface at runtime. Pair connectors with triggers to build event-driven automation: route an Outlook email to a sandbox that triages it with an AI agent, or react to a SharePoint file upload by extracting and processing the document all without writing glue code. Triggers can fire a shell command inside a sandbox or invoke an HTTP endpoint the sandbox exposes, so your automation shapes fit naturally around your workload. The integration is built on the new Connector Namespace service (az connector-namespace), the same runtime behind Logic Apps and Power Platform connectors, now available as a programmable layer for sandboxes. See the end-to-end samples for runnable azd up-deployable examples covering email triage and document automation scenarios. The Portal Experience Azure Container Apps Sandboxes are only available in the new Azure Container Apps portal that provides a rich, IDE-like experience for working with sandboxes. Creating a Sandbox The portal offers multiple creation paths: Standard Sandbox - full configuration control over source, resources, lifecycle, networking, and volumes GitHub Copilot Sandbox - preset, Copilot CLI ready to go, GitHub credentials can be wired through the Access Token before the sandbox is created Claude Sandbox - Claude CLI pre-installed, ready for agentic coding inside the sandbox Using Coding Agents (Copilot CLI / Claude Code) If you live inside Copilot CLI or Claude Code, you don't need to learn a new CLI. Install the azure-sandbox skill once and your agent picks up the right skills: # GitHub Copilot CLI # Add as a plugin marketplace /plugin marketplace add microsoft/azure-container-apps # Install all skills /plugin install sandboxes@Azure-Container-Apps # Claude Code claude plugin add microsoft/azure-container-apps The skill runs prerequisite checks silently (az --version, az account show, node --version, aca --version), prompts only if something's missing, and maps natural-language asks to the right aca commands. Bundled runbooks cover Copilot CLI BYOK (bring your own Azure OpenAI key), the deploy-a-web-app walkthrough, and shell setup. Sandbox Detail Page Once your sandbox is running, the detail page gives you immediate access to the sandbox terminal and additional details, such as - Network Audit - real-time egress traffic log showing allowed and denied requests Monitor - live CPU, memory, disk, and network utilization charts Connectors - attached connections with an "Add" action Volumes - mounted volumes with an "Add" action Log Stream - streaming container logs Processes - running process list inside the sandbox Files - file explorer to browse the sandbox filesystem The toolbar actions let you manage the state of the sandbox - Resume or Stop. In the Ellipsis menu (⁝) you can find additional settings to manage network Egress Policy and ingress (Add port), take a Snapshot of the sandbox, Commit (save disk state as a new disk image), set Lifecycle Policy or permanently Delete the sandbox. Finally, you can see additional Details in a side panel. Getting Started with the CLI and Python SDK All sandbox and sandbox-group operations go through the aca CLI. There are no az containerapp sandbox commands, - az is only used for az login, az account show, and resource-group management. Install (CLI) # Mac, Linux curl -fsSL https://aka.ms/aca-cli-install | sh # Windows irm https://aka.ms/aca-cli-install-ps | iex Run aca --help to get started. Install (Python SDK) pip install azure-containerapps-sandbox For more details, quick start and examples on ACA CLI and Python SDK, please go to https://sandboxes.azure.com Evolution from Dynamic Sessions If you've used Azure Container Apps Dynamic Sessions, Sandboxes are the next evolution of that capability. Everything Sessions can do, Sandboxes can do - and significantly more: Capability Dynamic Sessions Sandboxes Sub-second startup ✓ ✓ Strong isolation ✓ ✓ Custom container images ✓ ✓ Custom VNet integration ✓ (Partial) ✓ Suspend/resume with Memory and Disk snapshots - ✓ Lifecycle policies (auto-suspend, auto-delete) - ✓ Network egress policy (per-sandbox) - ✓ Persistent managed volumes (Blob, Data Disk) - ✓ Managed identity (system + user-assigned) - ✓ Secrets management - ✓ Configurable resource tiers - ✓ Direct access to sandbox in Portal experience - ✓ We will continue to support Dynamic Sessions, but all new investment goes into Sandboxes. If you're building new workloads on isolated ephemeral compute, start with Sandboxes. How It All Fits Together ACA Sandboxes is a platform primitive. It's the foundation on which multiple Microsoft products are already built - including ACA Express, Cloud sandboxes in GitHub Copilot, and Foundry Hosted Agents. When you build on Sandboxes, you're building on the same infrastructure that powers Microsoft's own portfolio. This is the evolution of what we shared with Project Legion in 2024. Legion described the internal infrastructure; Sandboxes exposes it as a customer-facing primitive that you can use directly. What's Next • Deeper Azure integrations - first-class connectivity with Azure networking, identity, storage, and AI services • Enhanced SDK and CLI - richer programmatic experiences for managing sandboxes at scale • More Microsoft services built on Sandboxes - this is just the beginning Get Started Today • Portal: https://sandboxes.azure.com/ • Documentation: Azure Container Apps Sandboxes • Pricing: Azure Container Apps Pricing (per-second vCPU/memory billing, scale-to-zero, snapshots at Blob Storage rates) We'd love to hear your feedback. You can ask questions, or file issues on the Azure Container Apps GitHub (prefix with [Sandbox] for Sandboxes-specific issues).9.6KViews3likes1Comment