<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Entra-Id | The .NET Blog</title><link>https://thedotnetblog.com/tags/entra-id/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>en</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Mon, 14 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/tags/entra-id/index.xml" rel="self" type="application/rss+xml"/><item><title>Cosmos DB Security for Day One: Start with Entra ID</title><link>https://thedotnetblog.com/news/emiliano-montesdeoca/cosmosdb-security-starter-guide/</link><pubDate>Mon, 14 Sep 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/news/emiliano-montesdeoca/cosmosdb-security-starter-guide/</guid><description>A practical security checklist for a new Cosmos DB app: identity-based access, scoped RBAC, network restrictions, parameterized queries, logging, and backup.</description><content:encoded>&lt;p&gt;Original source: &lt;a href="https://devblogs.microsoft.com/cosmosdb/im-starting-a-new-cosmos-db-app-what-security-do-i-actually-need/"&gt;I&amp;rsquo;m Starting a New Cosmos DB App. What Security Do I Actually Need?&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="the-common-mistake"&gt;The Common Mistake&lt;/h2&gt;
&lt;p&gt;You create a Cosmos DB account. Azure gives you two keys and a connection string. They work immediately, so they often make it into development, staging, and production before anyone revisits the decision.&lt;/p&gt;
&lt;p&gt;The problem is not that keys are complicated. They are bearer tokens. Anyone who has one can read, modify, or delete data, and shared keys do not give you reliable identity attribution. If one leaks into a log, screenshot, &lt;code&gt;.env&lt;/code&gt; file, or pull request, rotation means updating every dependent system that may have copied it.&lt;/p&gt;
&lt;p&gt;The source&amp;rsquo;s recommendation is straightforward: start with Entra ID from day one, including development, and make identity-based access the normal application path.&lt;/p&gt;
&lt;h2 id="control-plane-and-data-plane"&gt;Control Plane and Data Plane&lt;/h2&gt;
&lt;p&gt;A secure Cosmos DB setup starts with two separate questions.&lt;/p&gt;
&lt;p&gt;The control plane governs who can create or delete accounts, databases, and containers or change account settings. Azure RBAC manages that access. The data plane governs who can read, write, query, and delete documents. Cosmos DB RBAC manages the built-in data roles.&lt;/p&gt;
&lt;p&gt;A typical application should have data-plane access only, with the smallest role and scope it needs. Developers need their own identity for local work. CI/CD needs the permissions required to deploy, which may differ from what the application needs at runtime. Avoid giving every system the same connection string or credential.&lt;/p&gt;
&lt;p&gt;This distinction is easy to lose when an application is first created. Record it in infrastructure code and in the application&amp;rsquo;s deployment documentation so a broad control-plane permission does not quietly become the default.&lt;/p&gt;
&lt;h2 id="the-minimum-viable-setup"&gt;The Minimum Viable Setup&lt;/h2&gt;
&lt;h3 id="1-disable-local-authentication"&gt;1. Disable local authentication&lt;/h3&gt;
&lt;p&gt;Run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;az cosmosdb update --name &amp;lt;your-account&amp;gt; --resource-group &amp;lt;your-rg&amp;gt; --disable-local-auth &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Once disabled, keys no longer work and access requires an Entra ID identity. If you are not ready to disable keys, at minimum keep connection strings out of source control, use a secure store such as Key Vault, and enable secret scanning.&lt;/p&gt;
&lt;h3 id="2-give-the-app-an-identity"&gt;2. Give the app an identity&lt;/h3&gt;
&lt;p&gt;For App Service, Functions, Container Apps, AKS, or similar Azure compute, assign a system-assigned managed identity. For local development, use your developer identity through &lt;code&gt;az login&lt;/code&gt; or another supported credential. &lt;code&gt;DefaultAzureCredential&lt;/code&gt; lets the same SDK pattern work across those environments.&lt;/p&gt;
&lt;h3 id="3-assign-a-narrowly-scoped-data-role"&gt;3. Assign a narrowly scoped data role&lt;/h3&gt;
&lt;p&gt;The source highlights the Cosmos DB Built-in Data Reader and Built-in Data Contributor roles. Scope the assignment to the account, database, or container according to the actual need rather than defaulting to the broadest scope.&lt;/p&gt;
&lt;h3 id="4-connect-without-keys"&gt;4. Connect without keys&lt;/h3&gt;
&lt;p&gt;A .NET client can use the account endpoint with &lt;code&gt;DefaultAzureCredential&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Azure.Identity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Azure.Cosmos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CosmosClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;accountEndpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;https://&amp;lt;your-account&amp;gt;.documents.azure.com:443/&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tokenCredential&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The same code can use a developer login locally, managed identity in Azure, and a service principal or federated identity in CI/CD. That removes secrets from application configuration, but it does not remove the need to scope and audit the identity.&lt;/p&gt;
&lt;h3 id="5-turn-on-diagnostic-logging"&gt;5. Turn on diagnostic logging&lt;/h3&gt;
&lt;p&gt;Route diagnostic settings to Log Analytics before an incident. The source recommends categories such as &lt;code&gt;DataPlaneRequests&lt;/code&gt;, &lt;code&gt;QueryRuntimeStatistics&lt;/code&gt;, &lt;code&gt;PartitionKeyStatistics&lt;/code&gt;, and &lt;code&gt;ControlPlaneRequests&lt;/code&gt;. High-volume data-plane logs can be expensive, so choose retention and sampling deliberately.&lt;/p&gt;
&lt;h3 id="6-restrict-network-access"&gt;6. Restrict network access&lt;/h3&gt;
&lt;p&gt;The default endpoint is publicly reachable. Start with an IP allowlist for known office and CI/CD egress addresses, then evaluate Private Endpoints and VNet integration as the environment matures.&lt;/p&gt;
&lt;h3 id="7-parameterize-queries"&gt;7. Parameterize queries&lt;/h3&gt;
&lt;p&gt;Cosmos DB NoSQL accepts JSON, and the application is responsible for preventing malformed or injection-friendly query construction. Do not concatenate user input:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QueryDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SELECT * FROM c WHERE c.userId = @userId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;@userId&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Parameterization is necessary, but continue validating document shape, size, and authorization in the application.&lt;/p&gt;
&lt;h3 id="8-enable-continuous-backup"&gt;8. Enable continuous backup&lt;/h3&gt;
&lt;p&gt;Continuous backup provides point-in-time restore options for mistakes and other data loss scenarios. Choose the 7- or 30-day tier according to recovery requirements, and enable it at account creation when possible.&lt;/p&gt;
&lt;h2 id="what-can-wait"&gt;What Can Wait&lt;/h2&gt;
&lt;p&gt;The source deliberately separates day-one controls from later investments. Private Endpoints and VNet integration can follow an initial IP allowlist. Customer-managed keys may be required for compliance but add operational overhead. Microsoft Defender for Cosmos DB is strongly recommended once production data is present, but it does not replace identity, network, query, or backup basics.&lt;/p&gt;
&lt;p&gt;The expensive decision to postpone is identity. Migrating from keys later touches deployments, environments, and SDK calls. Starting with &lt;code&gt;DefaultAzureCredential&lt;/code&gt; avoids turning that migration into a breaking project.&lt;/p&gt;
&lt;h2 id="recommendations-for-net-teams"&gt;Recommendations for .NET Teams&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Put identity and role assignments in infrastructure code.&lt;/li&gt;
&lt;li&gt;Use separate developer, runtime, and deployment identities.&lt;/li&gt;
&lt;li&gt;Scope Cosmos DB roles to the smallest useful resource.&lt;/li&gt;
&lt;li&gt;Test logging, network restrictions, parameterization, and restore before production.&lt;/li&gt;
&lt;li&gt;Keep connection strings and keys out of source control even during the transition.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A secure Cosmos DB default is not an enterprise ceremony. It is choosing an identity boundary before the first business feature makes the insecure path difficult to change.&lt;/p&gt;</content:encoded></item></channel></rss>