{"id":7576,"date":"2026-09-08T15:56:57","date_gmt":"2026-09-08T20:56:57","guid":{"rendered":"https:\/\/andreas-wolter.com\/?p=7576"},"modified":"2026-09-08T16:04:21","modified_gmt":"2026-09-08T21:04:21","slug":"2609_azure_arc_sql_server_least_privilege_relies_on_sysadmin","status":"publish","type":"post","link":"https:\/\/andreas-wolter.com\/en\/2609_azure_arc_sql_server_least_privilege_relies_on_sysadmin\/","title":{"rendered":"Azure Arc for SQL Server: \u201cLeast Privilege\u201d Mode Still Relies on sysadmin"},"content":{"rendered":"\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-m0cxh8ps-c348f9acaf4be5be40a9eeaf447a0ef8\">\n#top .av-special-heading.av-m0cxh8ps-c348f9acaf4be5be40a9eeaf447a0ef8{\npadding-bottom:10px;\n}\nbody .av-special-heading.av-m0cxh8ps-c348f9acaf4be5be40a9eeaf447a0ef8 .av-special-heading-tag .heading-char{\nfont-size:25px;\n}\n.av-special-heading.av-m0cxh8ps-c348f9acaf4be5be40a9eeaf447a0ef8 .av-subheading{\nfont-size:15px;\n}\n<\/style>\n<div  class='av-special-heading av-m0cxh8ps-c348f9acaf4be5be40a9eeaf447a0ef8 av-special-heading-h3 blockquote modern-quote  avia-builder-el-0  el_before_av_textblock  avia-builder-el-first '><h3 class='av-special-heading-tag'  itemprop=\"headline\"  >Azure Arc for SQL Server: <span class='special_amp'>\u201c<\/span>Least Privilege<span class='special_amp'>\u201d<\/span> Mode Still Relies on sysadmin<\/h3><div class=\"special-heading-border\"><div class=\"special-heading-inner-border\"><\/div><\/div><\/div>\r\n\r\n<section  class='av_textblock_section av-m0cxgkjy-c935304b4106b45214698f40e83a9894 '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>Azure Arc for SQL Server comes with a so-called <strong>\u201cleast privilege mode.\u201d<\/strong><\/p>\n<p>But certain Azure Arc components still execute SQL Server operations with sysadmin authority, which can expose that authority to database-scoped code.<\/p>\n<p>Fabiano Amorim recently demonstrated how a database-scoped principal can take advantage of exactly this privileged execution context to escalate to sysadmin through a database-level DDL trigger: <a href=\"https:\/\/www.red-gate.com\/simple-talk\/data-security-privacy-compliance\/how-azure-arc-allows-a-db-admin-to-become-sql-server-sysadmin-the-vulnerability-explained\/\" target=\"_blank\" rel=\"noopener\">How Azure Arc allows a DB admin to become SQL Server sysadmin \u2013 the vulnerability explained<\/a><\/p>\n<p>Fabiano covers the exploit itself in detail. What I want to put under the magnifying glass here is the <strong>\u201cleast privilege\u201d mode itself<\/strong> &#8211; a topic I have written about extensively:<\/p>\n<p><a href=\"https:\/\/techcommunity.microsoft.com\/blog\/azuresqlblog\/security-the-principle-of-least-privilege-polp\/2067390\/\" target=\"_blank\" rel=\"noopener\">The Principle of Least Privilege (POLP)<\/a> \/ (<a href=\"https:\/\/andreas-wolter.com\/en\/202102_principle-of-least-privilege-polp\/\">Mirror<\/a>)<\/p>\n<h2>Least privilege \u2013 except for Deployer.exe<\/h2>\n<p>With least privilege enabled, the regular Azure Extension service runs under the restricted identity:<\/p>\n<p>NT SERVICE\\SqlServerExtension<\/p>\n<p>But there is a separate component involved: Deployer.exe.<\/p>\n<p>Deployer.exe runs as NT AUTHORITY\\SYSTEM and impersonates the SQL Server Database Engine service account when connecting to SQL Server.<\/p>\n<p>And Microsoft requires that service account to be a member of the SQL Server sysadmin fixed server role for this operation: <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/sql-server\/azure-arc\/configure-least-privilege?view=sql-server-ver17\" target=\"_blank\" rel=\"noopener\">Operate SQL Server enabled by Azure Arc with least privilege<\/a><\/p>\n<p>That is a clear deviation from the default security best practice.<\/p>\n<p>So even in \u201cleast privilege\u201d mode, certain Arc operations still reach SQL Server with full sysadmin authority.<\/p>\n<h2>The attack vector<\/h2>\n<p>Having a privileged setup component is not automatically a vulnerability.<\/p>\n<p>The problem is that Arc performs DDL inside user databases while retaining that privileged execution context.<\/p>\n<p>A database user with permission to create database-level DDL triggers can prepare a trigger and wait for an Azure Arc operation to fire it.<\/p>\n<p>The trigger then executes under the privileged caller&#8217;s context &#8211; in this case with sysadmin authority &#8211; and can perform server-level operations that the database user could never execute directly.<\/p>\n<p>Membership in db_ddladmin is sufficient to create such a trigger, can therefore become a path to sysadmin. Db_ddladmin is a powerful role and should be granted carefully. But it is not sysadmin.<\/p>\n<p>Otherwise, why would the distinction exist at all?<\/p>\n<p>Roles exist precisely to group defined permissions and make least-privilege administration practical.<\/p>\n<p>Saying that db_ddladmin is dangerous does not remove that distinction.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-7577 alignnone\" src=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/09\/202609_Azure_Arc_SQL_Server_sysadmin_least_privilege.png\" alt=\"\" width=\"711\" height=\"474\" srcset=\"https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/09\/202609_Azure_Arc_SQL_Server_sysadmin_least_privilege.png 1000w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/09\/202609_Azure_Arc_SQL_Server_sysadmin_least_privilege-300x200.png 300w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/09\/202609_Azure_Arc_SQL_Server_sysadmin_least_privilege-768x512.png 768w, https:\/\/andreas-wolter.com\/wp-content\/uploads\/2026\/09\/202609_Azure_Arc_SQL_Server_sysadmin_least_privilege-705x470.png 705w\" sizes=\"auto, (max-width: 711px) 100vw, 711px\" \/><\/p>\n<h2>This is where \u201cleast privilege\u201d becomes questionable<\/h2>\n<p>If a component needs sysadmin for a server-level task, that may be justified if SQL Server does not provide a more granular permission.<br \/>\nBut when it enters a user database and executes database-scoped DDL, it should not carry more authority than that operation requires.<\/p>\n<p>That is especially important in SQL Server because DDL can invoke database-controlled code such as triggers.<\/p>\n<p>Microsoft&#8217;s own SQL Server documentation warns about this class of permission hijacking: <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/triggers\/manage-trigger-security\" target=\"_blank\" rel=\"noopener\">Manage trigger security<\/a>. And Erland Sommarskog has written about this extensively here: <a href=\"https:\/\/www.sommarskog.se\/perm-hijack.html\" target=\"_blank\" rel=\"noopener\">Don&#8217;t Let Your Permissions be Hijacked!<\/a>.<\/p>\n<p>But other than telling administrators to be aware of the risk, SQL Server does not provide a practical general solution for eliminating the threat posed by such privilege-hijacking scenarios.<\/p>\n<p>And with Azure Arc, we now have a prominent Microsoft first-party example of exactly this problem.<\/p>\n<p>Unfortunately, SQL Server&#8217;s permission and role model still contains many exceptions where least privilege is difficult or impossible to implement cleanly.<\/p>\n<p>I am trying to maintain an accurate list here: <a href=\"https:\/\/andreas-wolter.com\/en\/least-privilege-sysadmin-required-sql-server\/\">The challenges for least privilege: When sysadmin is still required in Microsoft SQL Server<\/a>.<\/p>\n<p>While I worked at Microsoft, a significant part of my role focused on improving the SQL Server permission model, defining more granular permissions and roles, and making sure new functionality adhered to the Principle of Least Privilege.<\/p>\n<p>So I am familiar with both sides of the problem: the engineering challenges behind the scenes, and the practical difficulties customers and DBAs have encountered with SQL Server permissions over the past two decades.<\/p>\n<h2>A wish to the SQL Server Security team<\/h2>\n<p>I would urge Microsoft not to lose sight of these fundamentals while investing in new areas such as AI.<\/p>\n<p>There are still plenty of situations where ordinary users and DBAs cannot implement proper least privilege without workarounds, excessive permissions, or undocumented exceptions.<\/p>\n<p>And as this Azure Arc example shows, even Microsoft\u2019s own components can struggle with the same problem.<\/p>\n<p>With AI agents increasingly accessing databases, this becomes even more important. We can no longer assume that privilege-escalation paths require a human administrator who understands the system well enough to discover and exploit them manually.<\/p>\n<p>Please keep investing in the SQL Server permission model, more granular permissions, and better-defined security boundaries.<\/p>\n<p>There is still considerable work to do. Before I left Microsoft, I had already prepared specification work around more granular SQL Server permissions and least-privilege improvements that could serve as a starting point for some of this work.<\/p>\n<p>Stay secure!<\/p>\n<p>Andreas<\/p>\n<\/div><\/section>\r\n\r\n<div  class='flex_column av-vb4k9-5c390a090b8757fafe36b077b8d164ce av_one_full  avia-builder-el-2  el_after_av_textblock  el_before_av_social_share  first flex_column_div  column-top-margin'     ><div  class='hr av-7coejt-c2ec2e6fb5dfa2080806798514392349 hr-default  avia-builder-el-3  el_before_av_textblock  avia-builder-el-first '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div>\n<section  class='av_textblock_section av-6e2h5l-f15ae97e4272ea5736cfded1578c506a '   itemscope=\"itemscope\" itemtype=\"https:\/\/schema.org\/BlogPosting\" itemprop=\"blogPost\" ><div class='avia_textblock'  itemprop=\"text\" ><p>Azure Arc can introduce privilege paths that are easy to miss in a conventional SQL Server security review. My assessments focus on effective permissions, escalation paths, and configuration-risks &#8211; not just role membership.<\/p>\n<\/div><\/section>\n<div  class='avia-button-wrap av-4g244p-2af494449b3b22f01471083c0e1e5207-wrap avia-button-center  avia-builder-el-5  el_after_av_textblock  el_before_av_hr '>\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-4g244p-2af494449b3b22f01471083c0e1e5207\">\n#top #wrap_all .avia-button.av-4g244p-2af494449b3b22f01471083c0e1e5207{\nfont-size:14px;\nbackground-color:#75a823;\nborder-color:#75a823;\ncolor:#ffffff;\nbox-shadow: 0 0 5px 5px ;\ntransition:all 0.4s ease-in-out;\n}\n<\/style>\n<a href=\"https:\/\/sarpedonqualitylab.us\/sql-server-security-assessment\/\" class=\"avia-button av-4g244p-2af494449b3b22f01471083c0e1e5207 avia-icon_select-yes-left-icon avia-size-medium avia-position-center\" target=\"_blank\" rel=\"noopener\"><span class='avia_button_icon avia_button_icon_left' aria-hidden='true' data-av_icon='\ue832' data-av_iconfont='entypo-fontello'><\/span><span class='avia_iconbox_title' >Assess Your SQL Server Security<\/span><\/a><\/div>\n<div  class='hr av-2df7qh-97a70af29223f51de4e8a5134ac96e31 hr-default  avia-builder-el-6  el_after_av_button  avia-builder-el-last '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div><\/div><div  class='av-social-sharing-box av-5n5vpa-78ffdd9d224b4a246af65bdc00dce900 av-social-sharing-box-default  avia-builder-el-7  el_after_av_one_full  el_before_av_hr  av-social-sharing-box-fullwidth'><div class=\"av-share-box\"><h5 class='av-share-link-description av-no-toc '>Share article<\/h5><ul class=\"av-share-box-list noLightbox\"><li class='av-share-link av-social-link-facebook' ><a target=\"_blank\" aria-label=\"Share on Facebook\" href=\"https:\/\/www.facebook.com\/sharer.php?u=https:\/\/andreas-wolter.com\/en\/2609_azure_arc_sql_server_least_privilege_relies_on_sysadmin\/&amp;t=Azure%20Arc%20for%20SQL%20Server%3A%20%E2%80%9CLeast%20Privilege%E2%80%9D%20Mode%20Still%20Relies%20on%20sysadmin\" aria-hidden=\"false\" data-av_icon=\"\ue8f3\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on Facebook\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on Facebook<\/span><\/a><\/li><li class='av-share-link av-social-link-twitter' ><a target=\"_blank\" aria-label=\"Share on Twitter\" href=\"https:\/\/twitter.com\/share?text=Azure%20Arc%20for%20SQL%20Server%3A%20%E2%80%9CLeast%20Privilege%E2%80%9D%20Mode%20Still%20Relies%20on%20sysadmin&amp;url=https:\/\/andreas-wolter.com\/en\/?p=7576\" aria-hidden=\"false\" data-av_icon=\"\ue8f1\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on Twitter\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on Twitter<\/span><\/a><\/li><li class='av-share-link av-social-link-linkedin' ><a target=\"_blank\" aria-label=\"Share on LinkedIn\" href=\"https:\/\/linkedin.com\/shareArticle?mini=true&amp;title=Azure%20Arc%20for%20SQL%20Server%3A%20%E2%80%9CLeast%20Privilege%E2%80%9D%20Mode%20Still%20Relies%20on%20sysadmin&amp;url=https:\/\/andreas-wolter.com\/en\/2609_azure_arc_sql_server_least_privilege_relies_on_sysadmin\/\" aria-hidden=\"false\" data-av_icon=\"\ue8fc\" data-av_iconfont=\"entypo-fontello\" title=\"\" data-avia-related-tooltip=\"Share on LinkedIn\" rel=\"noopener\"><span class='avia_hidden_link_text'>Share on LinkedIn<\/span><\/a><\/li><\/ul><\/div><\/div>\r\n\r\n\n<style type=\"text\/css\" data-created_by=\"avia_inline_auto\" id=\"style-css-av-4ofg9q-c2108540b480aba02923089240a3a176\">\n#top .hr.hr-invisible.av-4ofg9q-c2108540b480aba02923089240a3a176{\nheight:50px;\n}\n<\/style>\n<div  class='hr av-4ofg9q-c2108540b480aba02923089240a3a176 hr-invisible  avia-builder-el-8  el_after_av_social_share  el_before_av_comments_list '><span class='hr-inner '><span class=\"hr-inner-style\"><\/span><\/span><\/div>\r\n\r\n<div  class='av-buildercomment av-284ftq-f5a1564cd6b8ffad6ce835e2d40de4b7  av-blog-meta-author-disabled av-blog-meta-html-info-disabled'><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":4,"featured_media":7577,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[57],"tags":[27,258],"class_list":["post-7576","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-security-en","tag-security-en","tag-sysadmin-en"],"_links":{"self":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/7576","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/comments?post=7576"}],"version-history":[{"count":2,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/7576\/revisions"}],"predecessor-version":[{"id":7580,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/posts\/7576\/revisions\/7580"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media\/7577"}],"wp:attachment":[{"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/media?parent=7576"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/categories?post=7576"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/andreas-wolter.com\/en\/wp-json\/wp\/v2\/tags?post=7576"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}