{"id":112709,"date":"2026-10-30T12:00:00","date_gmt":"2026-10-30T12:00:00","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=112709"},"modified":"2026-10-22T13:29:33","modified_gmt":"2026-10-22T13:29:33","slug":"how-to-secure-api-keys-in-microsoft-fabric-gen2-dataflows-with-azure-key-vault","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/data-analytics\/how-to-secure-api-keys-in-microsoft-fabric-gen2-dataflows-with-azure-key-vault\/","title":{"rendered":"How to secure API keys in Microsoft Fabric Gen2 dataflows with Azure Key Vault"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>If you\u2019ve ever developed a <a href=\"https:\/\/learn.microsoft.com\/en-us\/power-bi\/transform-model\/dataflows\/dataflows-introduction-self-service\" target=\"_blank\" rel=\"noreferrer noopener\">Gen1 dataflow<\/a> to connect to an external <a href=\"https:\/\/aws.amazon.com\/what-is\/api\/\" target=\"_blank\" rel=\"noreferrer noopener\">API (Application Programming Interface)<\/a>, you know the awkward moment when you have to paste an API key into the <a href=\"https:\/\/www.red-gate.com\/simple-talk\/data-analytics\/13-things-i-wish-i-knew-about-power-query\/\" target=\"_blank\" rel=\"noreferrer noopener\">Power Query<\/a> script. <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There it sits, in plain text, inside an artifact (the proper name for something like a semantic model, report or dataflow created in the service), with limited options for secret rotation or <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/learn\/schema-based-access-control-for-sql-server-databases\/#:~:text=Access%20control%20boils%20down%20to%20the%20principle%20that%20the%20users%20of%20an%20application%20should%20have%20permissions%20to%20view%2C%20modify%20or%20delete%20only%20the%20data%20in%20the%20live%20database%20that%20is%20relevant%20to%20their%20job.\" target=\"_blank\" rel=\"noreferrer noopener\">access control<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Thankfully, <a href=\"https:\/\/learn.microsoft.com\/en-us\/fabric\/data-factory\/dataflows-gen2-overview\" target=\"_blank\" rel=\"noreferrer noopener\">Gen2 dataflows<\/a> improve the story considerably &#8211; especially when <a href=\"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/securing-web-application-secrets-through-azure-key-vault\/\" target=\"_blank\" rel=\"noreferrer noopener\">Azure Key Vault<\/a>, <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/bi-sql-server\/how-to-build-metadata-driven-pipelines-in-microsoft-fabric\/\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Fabric pipelines<\/a>, and the newer parameters feature are combined.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>In this guide, I\u2019ll show you the pattern I now reach for when I need to pass API secrets into a Fabric Gen2 dataflow without leaving them in code or configuration.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-goal-keep-secrets-out-of-the-dataflow\">The goal: keep secrets out of the dataflow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A dataflow should not <em>contain<\/em> secrets. Instead, it should receive a secret at runtime, use it, and then forget it. Meaning: no keys in Power Query code, no keys saved inside the dataflow connection, and no keys visible in source control (if the dataflow is synced through <a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/bi-sql-server\/source-control-with-git-power-bi-and-microsoft-fabric\/\" target=\"_blank\" rel=\"noreferrer noopener\">Fabric Git Integration<\/a>) or log files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To make this work, we need Azure Key Vault as the secret store, a Fabric pipeline as the orchestrator, and public parameters on the Gen2 dataflow as the secure delivery mechanism.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-when-does-this-pattern-make-sense\">When does this pattern make sense?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This approach is useful whenever a dataflow must call an authenticated endpoint. Common examples include:<\/p>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li>Calling a <a href=\"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/build-a-rest-api-in-net-core\/\" target=\"_blank\" rel=\"noreferrer noopener\">REST API<\/a> that requires an API key or bearer token (e.g., <a href=\"https:\/\/azure.microsoft.com\/en-us\/products\/ai-foundry\" target=\"_blank\" rel=\"noreferrer noopener\">Azure Foundry<\/a> or <a href=\"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/getting-started-with-microsoft-graph-api\/\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Graph<\/a>).<br><br><\/li>\n\n\n\n<li>Connecting to a custom service that <em>does<\/em> <em>not<\/em> support <a href=\"https:\/\/oauth.net\/2\/\" target=\"_blank\" rel=\"noreferrer noopener\">OAuth<\/a>-based connections.<br><br><\/li>\n\n\n\n<li>Running the same dataflow against different environments, each with its own credentials.<\/li>\n<\/ul>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Bear in mind, this is not a replacement for native OAuth connections where they exist. If Fabric already offers a secure, first-class connector for your source, use that! This pattern simply fills in the gaps.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-what-you-need-to-get-started\">What you need to get started<\/h2>\n\n\n<div class=\"block-core-list\">\n<ul class=\"wp-block-list\">\n<li>A <strong>Microsoft Fabric workspace<\/strong> with Gen2 dataflow support and pipeline authoring enabled. You also need Admin rights to the workspace.<br><br><\/li>\n\n\n\n<li>A <strong>Fabric capacity<\/strong> that supports pipelines and dataflows. Note that some AI-powered Gen2 features require a paid capacity, but the public parameters feature itself does not rely on Copilot licensing.<br><br><\/li>\n\n\n\n<li>An <strong>Azure Key Vault<\/strong> in a subscription your Fabric workspace can reach.<br><br><\/li>\n\n\n\n<li>Permission to grant the Fabric workspace managed identity (a.k.a. a service principal) access to that vault.<\/li>\n<\/ul>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"h-the-complete-step-by-step-guide\">The complete step-by-step guide<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Here&#8217;s my step-by-step guide to the pattern I use to pass API secrets into a Fabric Gen2 dataflow without leaving them in code or configuration.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-store-the-secret-in-azure-key-vault-step-1\">How to store the secret in Azure Key Vault (step 1)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>First, we need to create a secret in Azure Key Vault for the API key or token &#8211; and, at the time of writing (mid-2026), this happens <em>outside<\/em> of Microsoft Fabric.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quite frankly, it&#8217;s a point of frustration for me; it would be nice if this existed IN Fabric itself. Anyway, complaints aside, see the official Microsoft documentation for creating an Azure Key Vault <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/key-vault\/general\/quick-create-portal\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For naming your key vault, I like to prefix it with \u201ckv-\u201d, to keep in line with <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/cloud-adoption-framework\/ready\/azure-best-practices\/resource-abbreviations\" target=\"_blank\" rel=\"noreferrer noopener\">Azure Abbreviations<\/a>. I then add something predictable such as <code>kv-fabric-key-storage<\/code> or <code>kv-dataflow-keys<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, go ahead and create a secret in Key Vault. I created the secret following <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/key-vault\/secrets\/quick-create-portal\" target=\"_blank\" rel=\"noreferrer noopener\">these directions<\/a>, and I copy the link to the secret.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Copy the secret identifier, which will look like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"676\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-34.png\" alt=\"image showing the secret identifier copied from the newly created Key Vault secret\" class=\"wp-image-112710\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-34.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-34-300x241.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-34-768x618.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Secret identifier copied from the newly created Key Vault secret<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll need the vault <em>and<\/em> the secret name later, so it\u2019s best to copy them to a temporary text editor file like Notepad.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You should also copy the Vault URI for the newly created Key Vault. This is located in the <em>Overview<\/em> section when working with Key Vault:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"121\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-35.png\" alt=\"an image showing the Vault URI shown on the Key Vault Overview page.\" class=\"wp-image-112711\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-35.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-35-300x43.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-35-768x111.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The Vault URI shown on the Key Vault Overview page<\/em><\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-grant-microsoft-fabric-access-to-azure-key-vault-step-2\">How to grant Microsoft Fabric access to Azure Key Vault (step 2)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>First,<\/strong> <strong>your pipeline needs permission to read the secret. The cleanest way to do this is to use the <a href=\"https:\/\/www.red-gate.com\/simple-talk\/other\/workspace-identity-and-resource-instance-rules-more-than-simple-features\/\" target=\"_blank\" rel=\"noreferrer noopener\">workspace managed identity<\/a>.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, let&#8217;s create a managed identity for the workspace. To do this, go to the <em>Workspace<\/em>, select <em>Workspace Settings<\/em>, and navigate to <em>Workspace Identity<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"308\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-36.png\" alt=\"an image showing the Workspace Settings page showing the Workspace Identity section\" class=\"wp-image-112713\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-36.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-36-300x110.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-36-768x282.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The Workspace Settings page showing the Workspace Identity section<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Then, select <em>+ Workspace Identity<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"308\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-37.png\" alt=\"an image showing the + Workspace Identity button used to create a new managed identity\" class=\"wp-image-112712\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-37.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-37-300x110.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-37-768x282.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The + Workspace Identity button used to create a new managed identity<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">It may take a couple of seconds to create (and the <em>Name<\/em> field may be missing, as is often the case):<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"250\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41.png\" alt=\"An image showing the newly-created workspace identity with the Name field temporarily blank.\" class=\"wp-image-112718\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41-300x89.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41-768x229.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Newly-created workspace identity with the Name field temporarily blank<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Rest assured, the <em>name<\/em> is the name of your workspace. Simply refresh the browser, go back to <em>Managed Identity<\/em>, and the name will appear:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"714\" height=\"677\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-46.png\" alt=\"An image showing Workspace identity showing its name after refreshing the browser.\" class=\"wp-image-112725\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-46.png 714w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-46-300x284.png 300w\" sizes=\"auto, (max-width: 714px) 100vw, 714px\" \/><figcaption class=\"wp-element-caption\"><em>Workspace identity showing its name after refreshing the browser<\/em><\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-granting-fabric-access-to-key-vault\">Granting Fabric access to Key Vault<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s now navigate to the Key Vault. Open it via the Azure portal and head to <em>Access control (IAM)<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"762\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-39.png\" alt=\"An image showing the Access control (IAM) page for the Key Vault\" class=\"wp-image-112715\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-39.png 554w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-39-218x300.png 218w\" sizes=\"auto, (max-width: 554px) 100vw, 554px\" \/><figcaption class=\"wp-element-caption\"><em>The Access control (IAM) page for the Key Vault<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now click <em>Add<\/em>, followed by <em>Add Role Assignment<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"835\" height=\"426\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-40.png\" alt=\"image showing Add Role Assignment option under Access control (IAM)\" class=\"wp-image-112716\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-40.png 835w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-40-300x153.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-40-768x392.png 768w\" sizes=\"auto, (max-width: 835px) 100vw, 835px\" \/><figcaption class=\"wp-element-caption\"><em>Add Role Assignment option under Access control (IAM)<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Find and select the <em>Key Vault Secrets Users<\/em> role in the <em>Role<\/em> tab:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"389\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-44.png\" alt=\"Image showing Key Vault Secrets User role selected on the Role tab\" class=\"wp-image-112723\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-44.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-44-300x139.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-44-768x356.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The Key Vault Secrets User role selected on the Role tab<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, navigate to the <em>Members<\/em> tab and make sure <em>User, group, or service principal<\/em> is selected:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"399\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-45.png\" alt=\"image showing Members tab with \u201cUser, group, or service principal\u201d selected\" class=\"wp-image-112724\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-45.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-45-300x143.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-45-768x365.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Members tab with \u201cUser, group, or service principal\u201d selected<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Click <em>Select members<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"738\" height=\"197\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-38.png\" alt=\"image showing Select members button on the Add role assignment screen\" class=\"wp-image-112714\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-38.png 738w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-38-300x80.png 300w\" sizes=\"auto, (max-width: 738px) 100vw, 738px\" \/><figcaption class=\"wp-element-caption\"><em>The Select members button on the Add role assignment screen<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, search for the workspace identity (the name of the workspace) and press <em>Select<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"964\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50.png\" alt=\"an image showing Workspace identity selected as a member in the role assignment search\" class=\"wp-image-112730\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50.png 756w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50-235x300.png 235w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><figcaption class=\"wp-element-caption\"><em>Workspace identity selected as a member in the role assignment search<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This will return you to the <em>Add role assignment<\/em> screen &#8211; from here, select <em>Review + assign<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"841\" height=\"681\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-47.png\" alt=\"An image showing Review + assign screen for the completed role assignment\" class=\"wp-image-112726\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-47.png 841w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-47-300x243.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-47-768x622.png 768w\" sizes=\"auto, (max-width: 841px) 100vw, 841px\" \/><figcaption class=\"wp-element-caption\"><em>Review + assign screen for the completed role assignment<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This will assign the identity to the role. You&#8217;ll then likely be returned to Azure Portal&#8217;s main page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-collect-the-workspace-identity-s-information-for-later-use-step-3\">How to collect the Workspace Identity\u2019s information for later use (step 3)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The Workspace Identity you&#8217;ve created will now be available in the <em>App Registrations<\/em> area of <a href=\"https:\/\/www.microsoft.com\/en-gb\/security\/business\/microsoft-entra\" target=\"_blank\" rel=\"noreferrer noopener\">Microsoft Entra<\/a>. We now need to collect some information for use later in setup. <\/strong><\/p>\n\n\n\n<div id=\"callout-block_dcd7feffe43df6a520a46793173f1240\" class=\"callout alignnone\">\n    <div class=\"child-last:mb-0 child-first:mt-0 bg-gray-50 dark:bg-gray-950 p-4xl my-3xl\">\n\n<p class=\"wp-block-paragraph\"><strong>What is a Workspace Identity?<\/strong><br>A Workspace Identity is a service principal in Microsoft Entra. <a href=\"https:\/\/learn.microsoft.com\/en-us\/fabric\/security\/workspace-identity\" target=\"_blank\" rel=\"noreferrer noopener\">Learn more<\/a>.<\/p>\n\n<\/div>\n<\/div> \n\n\n<p class=\"wp-block-paragraph\"><em><a href=\"https:\/\/portal.azure.com\/#view\/Microsoft_AAD_IAM\/ActiveDirectoryMenuBlade\/~\/Overview\" target=\"_blank\" rel=\"noreferrer noopener\">Click here<\/a> to access Microsoft Entra as a commercial user, if needed.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once you&#8217;re in Microsoft Entra, expand the <em>Manage<\/em> section &#8211; located on the left-hand navigation &#8211; and select <em>App Registration<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"468\" height=\"995\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-52.png\" alt=\"an image showing the App registrations option under the Manage section in Microsoft Entra\" class=\"wp-image-112734\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-52.png 468w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-52-141x300.png 141w\" sizes=\"auto, (max-width: 468px) 100vw, 468px\" \/><figcaption class=\"wp-element-caption\"><em>The App registrations option under the Manage section in Microsoft Entra<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-how-to-find-the-client-id-and-tenant-id\">How to find the Client ID and Tenant ID<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Select <em>All Applications<\/em> and search for the name of your workspace. This should match the name of the Workspace Identity you created earlier. Once you&#8217;ve found it, select the app link located under the <em>Display Name<\/em> column:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"250\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41.png\" alt=\"an image showing App registration search results filtered by the workspace name\" class=\"wp-image-112719\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41-300x89.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41-768x229.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>App registration search results filtered by the workspace name<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An overview screen will appear, from which we now need to copy the <em>Client Id<\/em> and <em>Tenant Id<\/em> to a text editor (e.g., Notepad) for use later on:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"554\" height=\"762\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-39.png\" alt=\"an image showing Application overview page showing the Client ID and Tenant ID fields\" class=\"wp-image-112717\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-39.png 554w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-39-218x300.png 218w\" sizes=\"auto, (max-width: 554px) 100vw, 554px\" \/><figcaption class=\"wp-element-caption\"><em>Application overview page showing the Client ID and Tenant ID fields<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-how-to-create-a-new-client-secret\">How to create a new client secret<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">We also need a Client Secret, so head to the <em>Certificates and Secrets<\/em> tab <em>(you may have to expand the Manage tab to see it):<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"493\" height=\"478\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-49.png\" alt=\"Image showing Certificates and Secrets tab for the app registration\" class=\"wp-image-112728\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-49.png 493w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-49-300x291.png 300w\" sizes=\"auto, (max-width: 493px) 100vw, 493px\" \/><figcaption class=\"wp-element-caption\"><em>The Certificates and Secrets tab for the app registration<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Click onto the <em>Client secrets<\/em> tab and then <em>+ New Client Secret<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"250\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41.png\" alt=\"image showing New client secret button under the Client secrets tab\" class=\"wp-image-112720\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41-300x89.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-41-768x229.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>New client secret button under the Client secrets tab<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This will open a panel where you can now name the secret (e.g., Fabric Pipeline Use) and set the expiration period. When done, select <em>Add button<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"841\" height=\"358\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-42.png\" alt=\"an image showing how to Add a client secret panel with name and expiration fields\" class=\"wp-image-112721\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-42.png 841w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-42-300x128.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-42-768x327.png 768w\" sizes=\"auto, (max-width: 841px) 100vw, 841px\" \/><figcaption class=\"wp-element-caption\"><em>Add a client secret panel with name and expiration fields<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The panel will close and the secret will be created. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Do note that this secret will only be visible while this page is open, so you should copy the value to the text editor where you have the client id and tenant id stored. Once you navigate away, the secret <em>cannot<\/em> be recovered.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"146\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-43.png\" alt=\"an image showing the newly-generated client secret value, visible only on this page\" class=\"wp-image-112722\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-43.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-43-300x52.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-43-768x133.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The newly-generated client secret value, visible only on this page<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is a good time to set a Calendar reminder for a week before the expiration of the client secret, so you know to update it! <strong>Forgetting to update the client secret could result in the pipeline breaking later on.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At this point, you should have the following stored safely: a copy of the Vault URI and the secret name for the Key Vault setup step, and a copy of the Client ID, Tenant ID, and Client Secret for this section of the setup process.<\/p>\n\n\n\n<section id=\"my-first-block-block_8eebd96deb06ec228eb653a917cc772c\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Subscribe to the Simple Talk newsletter<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            All the latest articles, guides, podcasts, and more &#8211; delivered straight to your inbox.                                    <\/div>\n            <\/div>\n                                            <a href=\"https:\/\/www.red-gate.com\/simple-talk\/subscribe\/\" class=\"btn btn--secondary btn--lg\" aria-label=\"Subscribe now: Subscribe to the Simple Talk newsletter\">Subscribe now<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-create-a-gen2-dataflow-with-a-public-parameter\">How to create a Gen2 dataflow with a public parameter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Open your Fabric workspace and create a new Dataflow Gen2. Then, inside the Power Query editor, create a parameter that will hold the API secret at runtime. <strong>Here&#8217;s exactly how to do that:<\/strong><\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-how-to-create-the-parameter\">How to create the parameter <\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Go to <em>Home &gt; Manage parameters &gt; New parameter<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"286\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-48.png\" alt=\"Image showing the Manage parameters menu path to create a new parameter\" class=\"wp-image-112727\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-48.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-48-300x102.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-48-768x261.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The Manage parameters menu path to create a new parameter<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Name it something like <code>API_SECRET<\/code>. I prefer to capitalize my parameters and not have any spaces, so as to make them distinguishable from tables and functions:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"964\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50.png\" alt=\"Image showing New parameter dialog with a name entered\" class=\"wp-image-112732\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50.png 756w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50-235x300.png 235w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><figcaption class=\"wp-element-caption\"><em>New parameter dialog with a name entered<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Set the type to <em>Text<\/em> and then set a default value of a non-sensitive placeholder (such as <em>placeholder<\/em>.) When finished, select <em>OK<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"493\" height=\"478\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-49.png\" alt=\"Image showing Parameter type set to Text with a placeholder default value\" class=\"wp-image-112729\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-49.png 493w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-49-300x291.png 300w\" sizes=\"auto, (max-width: 493px) 100vw, 493px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Parameter type set to Text with a placeholder default value<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note: I left the parameter optional here, but I like to make it required once I finally wire it up with a Fabric pipeline.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-how-to-expose-the-parameter-for-external-use\">How to expose the parameter for external use<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"h-how-to-expose-the-parameter-for-external-usego-to-home-options\">Go to <em>Home &gt; Options<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"170\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-51.png\" alt=\"Image showing the Home tab Options menu location\" class=\"wp-image-112733\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-51.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-51-300x61.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-51-768x155.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Home tab Options menu location<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Navigate to <em>Parameters<\/em> and check <em>Enable parameters to be discovered and override for execution<\/em>. Then, select <em>OK<\/em> to save the change:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"756\" height=\"964\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50.png\" alt=\"The Enable parameters to be discovered and override for execution setting\" class=\"wp-image-112731\" style=\"width:756px;height:auto\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50.png 756w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-50-235x300.png 235w\" sizes=\"auto, (max-width: 756px) 100vw, 756px\" \/><figcaption class=\"wp-element-caption\"><em>The &#8220;Enable parameters to be discovered and override for execution&#8221; setting<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, save the dataflow. I would choose <em>Save<\/em> instead of other options like <em>Save and Run<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>This is the public parameters feature. Without it, a pipeline cannot pass a value into the dataflow at runtime.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-use-the-parameter-in-power-query-step-5\">How to use the parameter in Power Query (step 5)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Inside your dataflow, use the <code>API_SECRET<\/code> parameter wherever the API call needs authentication. <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if you are calling a <code>REST<\/code> endpoint that expects an API key in a header, your Power Query might look like this:<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:tsql decode:true \">let\n    Source = Web.Contents(\n        \"https:\/\/api.example.com\/v1\/data\",\n        [\n            Headers = [#\"x-api-key\" = API_SECRET]\n        ]\n    ),\n    Json = Json.Document(Source)\nin\n    Json<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Notice that <code>API_SECRET<\/code> is a parameter reference, not a literal string. The actual value is injected at execution time.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-build-a-pipeline-that-retrieves-the-secret-and-passes-it-in-step-6\">How to build a pipeline that retrieves the secret and passes it in (step 6)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create a new pipeline in the same workspace using the instructions <a href=\"https:\/\/learn.microsoft.com\/en-us\/fabric\/data-factory\/create-first-pipeline-with-sample-data\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>. <strong>The pipeline has two jobs: fetch the secret from Key Vault, then run the dataflow<em> with<\/em> that secret supplied as a parameter.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-add-a-web-activity-to-read-the-secret-step-7\">How to add a web activity to read the secret (step 7)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Once you&#8217;ve created the pipeline, add a <em>Web Activity<\/em> to it:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"841\" height=\"45\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-53.png\" alt=\"an image showing Web activity added to the pipeline canvas\" class=\"wp-image-112737\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-53.png 841w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-53-300x16.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-53-768x41.png 768w\" sizes=\"auto, (max-width: 841px) 100vw, 841px\" \/><figcaption class=\"wp-element-caption\"><em>Web activity added to the pipeline canvas<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure to give the <em>Web Activity<\/em> a descriptive name:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"691\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-54.png\" alt=\"Image showing the Web activity renamed with a descriptive name\" class=\"wp-image-112738\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-54.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-54-300x247.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-54-768x632.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Web activity renamed with a descriptive name<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Expand the <em>Advanced<\/em> section and select the <em>Secure Output<\/em> checkbox. This will ensure that, when the secret is retrieved, it isn\u2019t saved as plain text in the output (a security problem):<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"566\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-55.png\" alt=\"image showing the Secure Output checkbox enabled under the Advanced section\" class=\"wp-image-112740\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-55.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-55-300x202.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-55-768x517.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The Secure Output checkbox enabled under the Advanced section<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, navigate to <em>Settings<\/em>, click the drop-down for <em>Connection<\/em>, and select <em>Browse all<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"69\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png\" alt=\"an image showing the Browse all connections option under the Web activity Settings tab\" class=\"wp-image-112745\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-300x25.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-768x63.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The &#8220;Browse all connections&#8221; option under the &#8220;Web activity Settings&#8221; tab<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A pop-up will appear &#8211; here, pick <em>Web v2<\/em> under the <em>New Sources<\/em> section:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"69\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png\" alt=\"The Web v2 connector selected under the New Sources section\" class=\"wp-image-112744\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-300x25.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-768x63.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The Web v2 connector selected under the New Sources section<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are several things to fill out from here, and you <em>must<\/em> copy and paste the values correctly. Here&#8217;s a table I put together to map them for you:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>Property<\/strong><\/td><td><strong>Value<\/strong><\/td><\/tr><\/thead><tbody><tr><td>Base Url<\/td><td>Copy the Vault URI into this field<\/td><\/tr><tr><td>Token Audience Url<\/td><td>Enter https:\/\/vault.azure.net<\/td><\/tr><tr><td>Authentication Kind<\/td><td>Service Principal<\/td><\/tr><tr><td>Tenant ID<\/td><td>Copy the \u2018Tenant ID\u2019 value you saved in a prior step<\/td><\/tr><tr><td>Service principal client ID<\/td><td>Copy the \u2018Client ID\u2019 you saved in a prior step<\/td><\/tr><tr><td>Service Principal Key<\/td><td>Copy the \u2018Client Secret\u2019 you saved in a prior step<\/td><\/tr><tr><td>Privacy Level<\/td><td>Enter Organizational<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">When finished, click <em>Connect<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"69\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png\" alt=\"an image showing the Connect button used to finish creating the Web v2 connection\" class=\"wp-image-112741\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-300x25.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-768x63.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The Connect button used to finish creating the Web v2 connection<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This will return the <em>Settings<\/em> section for the <em>Web Activity<\/em>. We then need to set the <em>Relative URL<\/em> value. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This value will be in the format of <code>\/secrets\/{Secret Name}?api-version=7.4<\/code>, with <code>{Secret Name}<\/code> replaced by the name of the secret you created in the Key Vault. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I called mine <em>ApiKey<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"69\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png\" alt=\"image showing the relative URL field set to the Key Vault secret path and API version\" class=\"wp-image-112743\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-300x25.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-768x63.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The relative URL field set to the Key Vault secret path and API version<\/em><\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"h-how-to-add-a-set-variable-activity\">How to add a set variable activity<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"h-how-to-add-a-set-variable-acitivitynow-create-a-set-variable-activity\">Create a <em>Set Variable<\/em> activity:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"69\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png\" alt=\"Set Variable activity added to the pipeline canvas\" class=\"wp-image-112747\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-300x25.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-56-768x63.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Set Variable activity added to the pipeline canvas<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, connect the <em>Web Activity<\/em> with the <em>Set Variable<\/em> activity:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"839\" height=\"51\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-58.png\" alt=\"Web activity connected to the Set Variable activity\" class=\"wp-image-112746\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-58.png 839w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-58-300x18.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-58-768x47.png 768w\" sizes=\"auto, (max-width: 839px) 100vw, 839px\" \/><figcaption class=\"wp-element-caption\"><em>Web activity connected to the Set Variable activity<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the <em>General <\/em>section for the <em>Set Variable<\/em> activity, set a descriptive name, then check the <em>Secure Output<\/em> checkbox. This ensures the Key Vault secret continues to be secure:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"451\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-61.png\" alt=\"Set Variable activity renamed with Secure Output enabled\" class=\"wp-image-112750\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-61.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-61-300x161.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-61-768x412.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Set Variable activity renamed with Secure Output enabled<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Navigate to <em>Settings<\/em> and click <em>+ New<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"187\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-57.png\" alt=\"+ New button under the Set Variable activity\u2019s Settings tab\" class=\"wp-image-112739\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-57.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-57-300x67.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-57-768x171.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>+ New button under the Set Variable activity\u2019s Settings tab<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An <em>Add new variable<\/em> popup will appear. Give the variable a descriptive name (and make sure to keep the type as &#8216;string&#8217;). When finished, select <em>Confirm<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"811\" height=\"544\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-60.png\" alt=\"The \u201cAdd new variable\u201d popup with the string type selected\" class=\"wp-image-112749\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-60.png 811w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-60-300x201.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-60-768x515.png 768w\" sizes=\"auto, (max-width: 811px) 100vw, 811px\" \/><figcaption class=\"wp-element-caption\"><em>The &#8220;Add new variable\u201d popup with the string type selected<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This will return you to <em>Settings<\/em>, where you should now set the <em>Value<\/em> field to <code>@activity('WebActivityName').output.value<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>'WebActivityName'<\/code> should be the name of the prior <em>Web Activity<\/em> step. For me, this is<br><code>@activity('Get API Key from Key Vault').output.value<\/code><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"200\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64.png\" alt=\"an image showing The Variable Value field referencing the Web activity\u2019s output\" class=\"wp-image-112754\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64-300x71.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64-768x183.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>The Variable Value field referencing the Web activity\u2019s output<\/em><\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-add-a-dataflow-activity-and-map-the-parameter\">How to add a dataflow activity and map the parameter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The last activity we need to create is a <em>Dataflow<\/em> activity. Click <em>Dataflow:<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"839\" height=\"51\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-58.png\" alt=\"Dataflow activity added to the pipeline canvas\" class=\"wp-image-112742\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-58.png 839w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-58-300x18.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-58-768x47.png 768w\" sizes=\"auto, (max-width: 839px) 100vw, 839px\" \/><figcaption class=\"wp-element-caption\"><em>Dataflow activity added to the pipeline canvas<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once it&#8217;s created, connect the <em>Set Variable<\/em> activity with the new <em>Dataflow<\/em> activity:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"767\" height=\"249\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-59.png\" alt=\"Set the Variable activity connected to the Dataflow activity\" class=\"wp-image-112748\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-59.png 767w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-59-300x97.png 300w\" sizes=\"auto, (max-width: 767px) 100vw, 767px\" \/><figcaption class=\"wp-element-caption\"><em>Set the Variable activity connected to the Dataflow activity<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In <em>General Settings<\/em>, give the activity a descriptive name, then click the <em>Secure Input<\/em> checkbox:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"200\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64.png\" alt=\"General settings for the Dataflow activity with Secure Input enabled\" class=\"wp-image-112755\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64-300x71.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64-768x183.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>General settings for the Dataflow activity with Secure Input enabled<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, in the <em>Settings<\/em> section, set <em>Dataflow <\/em>to the dataflow we set up in the previous step:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"200\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64.png\" alt=\"Dataflow activity Settings tab pointing to the Gen2 dataflow\" class=\"wp-image-112753\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64-300x71.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-64-768x183.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Dataflow activity Settings tab pointing to the Gen2 dataflow<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can then expand <em>Dataflow parameters<\/em>, click on the <em>placeholder<\/em> value, and paste in the following:<br><code>@variables('str-api-key')<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here, <code>\u2018str-api-key\u2019<\/code> was the name of the variable you set in the previous step (not the <em>activity<\/em> name, but the name of the <em>variable<\/em>.)<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"313\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-62.png\" alt=\"Dataflow parameter value mapped to the pipeline variable\" class=\"wp-image-112751\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-62.png 840w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-62-300x112.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-62-768x286.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption class=\"wp-element-caption\"><em>Dataflow parameter value mapped to the pipeline variable<\/em><\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-how-to-test-the-pipeline-step-7\">How to test the pipeline (step 7)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Run the pipeline and monitor the output. If everything is configured correctly, the dataflow will authenticate successfully:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"841\" height=\"307\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-63.png\" alt=\"The pipeline run history, showing a successful execution\" class=\"wp-image-112752\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-63.png 841w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-63-300x110.png 300w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2026\/08\/image-63-768x280.png 768w\" sizes=\"auto, (max-width: 841px) 100vw, 841px\" \/><figcaption class=\"wp-element-caption\"><em>The pipeline run history, showing a successful execution<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, if it <em>does<\/em> fail, check that the workspace identity does <em>not<\/em> have Key Vault permissions, and the parameter is <em>not<\/em> marked as &#8216;public&#8217; in the dataflow. Also ensure that the dataflow wasn&#8217;t saved <em>after<\/em> enabling public parameters.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, make sure the Key Vault URL includes <code>?api-version=7.4<\/code>, and that the resource is set correctly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-lessons-learned-and-notable-quirks\">Lessons learned (and notable quirks)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Public parameters in Gen2 dataflows are powerful but come with a few rough edges. Here&#8217;s everything I learned (the hard way!) to help you avoid making the same mistakes.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-public-parameters-must-be-explicitly-enabled\">Public parameters <em>must<\/em> be explicitly enabled<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s easy to create a parameter, assume it&#8217;s public, and then wonder why it&#8217;s not showing in the pipeline. <strong>You must open <em>Options &gt; Parameters<\/em>, enable the public parameter toggle, and save the dataflow. These are crucial steps: skip any and the pipeline will not surface the parameter!<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-required-vs-optional-parameters-really-do-matter\">Required vs optional parameters really do matter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>If you mark a parameter as <em>required<\/em>, the pipeline must supply a value or the run fails.<\/strong> If it&#8217;s optional, the dataflow falls back to its default value. I usually keep API secrets required &#8211; this way, the pipeline fails fast if the Key Vault step is misconfigured.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-secure-output-is-helpful-but-not-magic\">Secure output is helpful but not magic!<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Enabling <em>Secure Output<\/em> and <em>Secure Input<\/em> on the activities masks the value of the secret in pipeline logs<\/strong>, which is good. However, <strong>once the value is inside the dataflow, it&#8217;s still a string. Do not write it to a table, or return it in a query result.<\/strong> Treat it as you would any other runtime credential.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-plain-text-may-be-a-necessary-evil-during-development\">Plain text may be a necessary evil during development<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Walking through this process, you can imagine that debugging a dataflow by having to run a pipeline each time could be time consuming. <strong>I&#8217;ve found that putting the secret in the Power Query parameter temporarily allows me to test the dataflow. <\/strong>Just be careful to expire that secret when you\u2019re ready to use the pipeline &#8211; and use a different secret for the pipeline than the one used for developing\/debugging!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Additionally, <strong>I wouldn&#8217;t commit the Gen2 dataflow to Git (using Git Integration) until <em>after<\/em> you&#8217;ve put a placeholder value in the Power Query parameter.<\/strong> <strong>Otherwise, the secret gets stored in plain text in your repository, which is a security issue.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Gen2 dataflows give us a much better secret-handling story than Gen1. By storing secrets in Azure Key Vault, retrieving them in a Fabric pipeline, and passing them through public parameters, you can keep API keys out of your dataflow code <em>and <\/em>out of source control. <\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The pattern takes a few extra steps, but the security and operational benefits are worth it. Watch out for the quirks around enabling public parameters and required fields, and always treat the injected values as runtime credentials that should <em>never<\/em> be logged or persisted.<\/p>\n\n\n\n<section id=\"my-first-block-block_00b59fc49b6d2b17b5c282bb56ba518b\" class=\"my-first-block alignwide\">\n    <div class=\"bg-brand-600 text-base-white py-5xl px-4xl rounded-sm bg-gradient-to-r from-brand-600 to-brand-500 red\">\n        <div class=\"gap-4xl items-start md:items-center flex flex-col md:flex-row justify-between\">\n            <div class=\"flex-1 col-span-10 lg:col-span-7\">\n                <h3 class=\"mt-0 font-display mb-2 text-display-sm\">Simple Talk is brought to you by Redgate Software<\/h3>\n                <div class=\"child:last-of-type:mb-0\">\n                                            Take control of your databases with the trusted Database DevOps solutions provider. Automate with confidence, scale securely, and unlock growth through AI.                                    <\/div>\n            <\/div>\n                                            <a href=\"https:\/\/www.red-gate.com\/solutions\/overview\/\" class=\"btn btn--secondary btn--lg\" aria-label=\"Discover how Redgate can help you: Simple Talk is brought to you by Redgate Software\">Discover how Redgate can help you<\/a>\n                    <\/div>\n    <\/div>\n<\/section>\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. Can I use Azure Key Vault secrets directly in a Gen1 dataflow?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">No. Gen1 dataflows don&#8217;t support runtime parameter injection from a pipeline, so any API key referenced in Power Query is stored in plain text within the dataflow itself. This pattern -Key Vault, a Fabric pipeline, and public parameters &#8211; requires a Gen2 dataflow, since only Gen2 supports parameters that a pipeline can override at execution time.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. What permissions does my Fabric workspace need to access Key Vault?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">The Fabric workspace needs its own managed identity (created under Workspace Settings &gt; Workspace Identity), and that identity must be assigned the Key Vault Secrets User role in the vault&#8217;s Access Control (IAM) settings. Without this role assignment, the pipeline&#8217;s Web Activity will fail to retrieve the secret at runtime.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. Should Gen2 dataflow parameters be required or optional?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">For API secrets, mark the parameter as required rather than optional. A required parameter forces the pipeline to supply a value or the run fails immediately, which surfaces misconfiguration (like a broken Key Vault connection) right away. An optional parameter silently falls back to its default, potentially masking authentication errors.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">4. Does enabling Secure Output fully protect my API key in Fabric pipelines?<\/h3>\n            <div class=\"faq-answer\">\n                <p dir=\"ltr\">Secure Output and Secure Input hide the secret&#8217;s value from pipeline run logs and activity outputs, which is important. However, once inside the dataflow, the secret exists as a plain string in memory &#8211; so it can still be exposed if written to a table or returned in a query result.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">5. Is it safe to commit a Gen2 dataflow with public parameters to Git?<\/h3>\n            <div class=\"faq-answer\">\n                <div role=\"feed\" aria-label=\"Chat messages\" aria-describedby=\"_r_161_\">\n<div>\n<div>\n<div tabindex=\"0\" role=\"article\" aria-label=\"Message 2 of 2\">\n<div>\n<div>\n<div>\n<div>\n<div>\n<div>\n<div>\n<div>\n<div>\n<div>\n<div>\n<div>\n<div>\n<p dir=\"ltr\">Yes, as long as the parameter&#8217;s default value is a non-sensitive placeholder before committing. If an actual API key is left in the Power Query parameter&#8217;s default value when the dataflow syncs through Fabric Git Integration, that secret will be stored in plain text in the repository.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n            <\/div>\n            <\/section>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to pass API secrets into Microsoft Fabric Gen2 dataflows using Azure Key Vault, pipelines, and public parameters (no keys in code.)&hellip;<\/p>\n","protected":false},"author":344919,"featured_media":105472,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[137091,10,159160,53,159164,159166],"tags":[5364,4178,5992,4168,158997,101611],"coauthors":[159224],"class_list":["post-112709","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure","category-cloud","category-data-analytics","category-featured","category-microsoft-fabric","category-powerbi","tag-azure","tag-bi","tag-data-analysis","tag-database","tag-microsoft-fabric","tag-power-bi"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/112709","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/344919"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=112709"}],"version-history":[{"count":12,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/112709\/revisions"}],"predecessor-version":[{"id":112874,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/112709\/revisions\/112874"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media\/105472"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=112709"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=112709"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=112709"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=112709"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}