How to secure API keys in Microsoft Fabric Gen2 dataflows with Azure Key Vault

Comments 0

Share to social media

If you’ve ever developed a Gen1 dataflow to connect to an external API (Application Programming Interface), you know the awkward moment when you have to paste an API key into the Power Query script.

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 access control.

Thankfully, Gen2 dataflows improve the story considerably – especially when Azure Key Vault, Microsoft Fabric pipelines, and the newer parameters feature are combined.

In this guide, I’ll 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.

The goal: keep secrets out of the dataflow

A dataflow should not contain 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 Fabric Git Integration) or log files.

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.

When does this pattern make sense?

This approach is useful whenever a dataflow must call an authenticated endpoint. Common examples include:

  • Calling a REST API that requires an API key or bearer token (e.g., Azure Foundry or Microsoft Graph).

  • Connecting to a custom service that does not support OAuth-based connections.

  • Running the same dataflow against different environments, each with its own credentials.

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.

What you need to get started

  • A Microsoft Fabric workspace with Gen2 dataflow support and pipeline authoring enabled. You also need Admin rights to the workspace.

  • A Fabric capacity 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.

  • An Azure Key Vault in a subscription your Fabric workspace can reach.

  • Permission to grant the Fabric workspace managed identity (a.k.a. a service principal) access to that vault.

The complete step-by-step guide

Here’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.

How to store the secret in Azure Key Vault (step 1)

First, we need to create a secret in Azure Key Vault for the API key or token – and, at the time of writing (mid-2026), this happens outside of Microsoft Fabric.

Quite frankly, it’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 here.

For naming your key vault, I like to prefix it with “kv-”, to keep in line with Azure Abbreviations. I then add something predictable such as kv-fabric-key-storage or kv-dataflow-keys.

So, go ahead and create a secret in Key Vault. I created the secret following these directions, and I copy the link to the secret.

Copy the secret identifier, which will look like this:

image showing the secret identifier copied from the newly created Key Vault secret
Secret identifier copied from the newly created Key Vault secret

You’ll need the vault and the secret name later, so it’s best to copy them to a temporary text editor file like Notepad.

You should also copy the Vault URI for the newly created Key Vault. This is located in the Overview section when working with Key Vault:

an image showing the Vault URI shown on the Key Vault Overview page.
The Vault URI shown on the Key Vault Overview page

How to grant Microsoft Fabric access to Azure Key Vault (step 2)

First, your pipeline needs permission to read the secret. The cleanest way to do this is to use the workspace managed identity.

So, let’s create a managed identity for the workspace. To do this, go to the Workspace, select Workspace Settings, and navigate to Workspace Identity:

an image showing the Workspace Settings page showing the Workspace Identity section
The Workspace Settings page showing the Workspace Identity section

Then, select + Workspace Identity:

an image showing the + Workspace Identity button used to create a new managed identity
The + Workspace Identity button used to create a new managed identity

It may take a couple of seconds to create (and the Name field may be missing, as is often the case):

An image showing the newly-created workspace identity with the Name field temporarily blank.
Newly-created workspace identity with the Name field temporarily blank

Rest assured, the name is the name of your workspace. Simply refresh the browser, go back to Managed Identity, and the name will appear:

An image showing Workspace identity showing its name after refreshing the browser.
Workspace identity showing its name after refreshing the browser

Granting Fabric access to Key Vault

Let’s now navigate to the Key Vault. Open it via the Azure portal and head to Access control (IAM):

An image showing the Access control (IAM) page for the Key Vault
The Access control (IAM) page for the Key Vault

Now click Add, followed by Add Role Assignment:

image showing Add Role Assignment option under Access control (IAM)
Add Role Assignment option under Access control (IAM)

Find and select the Key Vault Secrets Users role in the Role tab:

Image showing Key Vault Secrets User role selected on the Role tab
The Key Vault Secrets User role selected on the Role tab

Next, navigate to the Members tab and make sure User, group, or service principal is selected:

image showing Members tab with “User, group, or service principal” selected
Members tab with “User, group, or service principal” selected

Click Select members:

image showing Select members button on the Add role assignment screen
The Select members button on the Add role assignment screen

Then, search for the workspace identity (the name of the workspace) and press Select:

an image showing Workspace identity selected as a member in the role assignment search
Workspace identity selected as a member in the role assignment search

This will return you to the Add role assignment screen – from here, select Review + assign:

An image showing Review + assign screen for the completed role assignment
Review + assign screen for the completed role assignment

This will assign the identity to the role. You’ll then likely be returned to Azure Portal’s main page.

How to collect the Workspace Identity’s information for later use (step 3)

The Workspace Identity you’ve created will now be available in the App Registrations area of Microsoft Entra. We now need to collect some information for use later in setup.

What is a Workspace Identity?
A Workspace Identity is a service principal in Microsoft Entra. Learn more.

Click here to access Microsoft Entra as a commercial user, if needed.

Once you’re in Microsoft Entra, expand the Manage section – located on the left-hand navigation – and select App Registration:

an image showing the App registrations option under the Manage section in Microsoft Entra
The App registrations option under the Manage section in Microsoft Entra

How to find the Client ID and Tenant ID

Select All Applications and search for the name of your workspace. This should match the name of the Workspace Identity you created earlier. Once you’ve found it, select the app link located under the Display Name column:

an image showing App registration search results filtered by the workspace name
App registration search results filtered by the workspace name

An overview screen will appear, from which we now need to copy the Client Id and Tenant Id to a text editor (e.g., Notepad) for use later on:

an image showing Application overview page showing the Client ID and Tenant ID fields
Application overview page showing the Client ID and Tenant ID fields

How to create a new client secret

We also need a Client Secret, so head to the Certificates and Secrets tab (you may have to expand the Manage tab to see it):

Image showing Certificates and Secrets tab for the app registration
The Certificates and Secrets tab for the app registration

Click onto the Client secrets tab and then + New Client Secret:

image showing New client secret button under the Client secrets tab
New client secret button under the Client secrets tab

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 Add button:

an image showing how to Add a client secret panel with name and expiration fields
Add a client secret panel with name and expiration fields

The panel will close and the secret will be created.

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 cannot be recovered.

an image showing the newly-generated client secret value, visible only on this page
The newly-generated client secret value, visible only on this page

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! Forgetting to update the client secret could result in the pipeline breaking later on.

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.

Subscribe to the Simple Talk newsletter

All the latest articles, guides, podcasts, and more – delivered straight to your inbox.
Subscribe now

How to create a Gen2 dataflow with a public parameter

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. Here’s exactly how to do that:

How to create the parameter

Go to Home > Manage parameters > New parameter:

Image showing the Manage parameters menu path to create a new parameter
The Manage parameters menu path to create a new parameter

Name it something like API_SECRET. I prefer to capitalize my parameters and not have any spaces, so as to make them distinguishable from tables and functions:

Image showing New parameter dialog with a name entered
New parameter dialog with a name entered

Set the type to Text and then set a default value of a non-sensitive placeholder (such as placeholder.) When finished, select OK:

Image showing Parameter type set to Text with a placeholder default value

Parameter type set to Text with a placeholder default value

Note: I left the parameter optional here, but I like to make it required once I finally wire it up with a Fabric pipeline.

How to expose the parameter for external use

Go to Home > Options:

Image showing the Home tab Options menu location
Home tab Options menu location

Navigate to Parameters and check Enable parameters to be discovered and override for execution. Then, select OK to save the change:

The Enable parameters to be discovered and override for execution setting
The “Enable parameters to be discovered and override for execution” setting

Now, save the dataflow. I would choose Save instead of other options like Save and Run.

This is the public parameters feature. Without it, a pipeline cannot pass a value into the dataflow at runtime.

How to use the parameter in Power Query (step 5)

Inside your dataflow, use the API_SECRET parameter wherever the API call needs authentication.

For example, if you are calling a REST endpoint that expects an API key in a header, your Power Query might look like this:

Notice that API_SECRET is a parameter reference, not a literal string. The actual value is injected at execution time.

How to build a pipeline that retrieves the secret and passes it in (step 6)

Create a new pipeline in the same workspace using the instructions here. The pipeline has two jobs: fetch the secret from Key Vault, then run the dataflow with that secret supplied as a parameter.

How to add a web activity to read the secret (step 7)

Once you’ve created the pipeline, add a Web Activity to it:

an image showing Web activity added to the pipeline canvas
Web activity added to the pipeline canvas

Make sure to give the Web Activity a descriptive name:

Image showing the Web activity renamed with a descriptive name
Web activity renamed with a descriptive name

Expand the Advanced section and select the Secure Output checkbox. This will ensure that, when the secret is retrieved, it isn’t saved as plain text in the output (a security problem):

image showing the Secure Output checkbox enabled under the Advanced section
The Secure Output checkbox enabled under the Advanced section

Then, navigate to Settings, click the drop-down for Connection, and select Browse all:

an image showing the Browse all connections option under the Web activity Settings tab
The “Browse all connections” option under the “Web activity Settings” tab

A pop-up will appear – here, pick Web v2 under the New Sources section:

The Web v2 connector selected under the New Sources section
The Web v2 connector selected under the New Sources section

There are several things to fill out from here, and you must copy and paste the values correctly. Here’s a table I put together to map them for you:

PropertyValue
Base UrlCopy the Vault URI into this field
Token Audience UrlEnter https://vault.azure.net
Authentication KindService Principal
Tenant IDCopy the ‘Tenant ID’ value you saved in a prior step
Service principal client IDCopy the ‘Client ID’ you saved in a prior step
Service Principal KeyCopy the ‘Client Secret’ you saved in a prior step
Privacy LevelEnter Organizational

When finished, click Connect:

an image showing the Connect button used to finish creating the Web v2 connection
The Connect button used to finish creating the Web v2 connection

This will return the Settings section for the Web Activity. We then need to set the Relative URL value.

This value will be in the format of /secrets/{Secret Name}?api-version=7.4, with {Secret Name} replaced by the name of the secret you created in the Key Vault.

I called mine ApiKey:

image showing the relative URL field set to the Key Vault secret path and API version
The relative URL field set to the Key Vault secret path and API version

How to add a set variable activity

Create a Set Variable activity:

Set Variable activity added to the pipeline canvas
Set Variable activity added to the pipeline canvas

Then, connect the Web Activity with the Set Variable activity:

Web activity connected to the Set Variable activity
Web activity connected to the Set Variable activity

In the General section for the Set Variable activity, set a descriptive name, then check the Secure Output checkbox. This ensures the Key Vault secret continues to be secure:

Set Variable activity renamed with Secure Output enabled
Set Variable activity renamed with Secure Output enabled

Navigate to Settings and click + New:

+ New button under the Set Variable activity’s Settings tab
+ New button under the Set Variable activity’s Settings tab

An Add new variable popup will appear. Give the variable a descriptive name (and make sure to keep the type as ‘string’). When finished, select Confirm:

The “Add new variable” popup with the string type selected
The “Add new variable” popup with the string type selected

This will return you to Settings, where you should now set the Value field to @activity('WebActivityName').output.value

'WebActivityName' should be the name of the prior Web Activity step. For me, this is
@activity('Get API Key from Key Vault').output.value

an image showing The Variable Value field referencing the Web activity’s output
The Variable Value field referencing the Web activity’s output

How to add a dataflow activity and map the parameter

The last activity we need to create is a Dataflow activity. Click Dataflow:

Dataflow activity added to the pipeline canvas
Dataflow activity added to the pipeline canvas

Once it’s created, connect the Set Variable activity with the new Dataflow activity:

Set the Variable activity connected to the Dataflow activity
Set the Variable activity connected to the Dataflow activity

In General Settings, give the activity a descriptive name, then click the Secure Input checkbox:

General settings for the Dataflow activity with Secure Input enabled
General settings for the Dataflow activity with Secure Input enabled

Then, in the Settings section, set Dataflow to the dataflow we set up in the previous step:

Dataflow activity Settings tab pointing to the Gen2 dataflow
Dataflow activity Settings tab pointing to the Gen2 dataflow

You can then expand Dataflow parameters, click on the placeholder value, and paste in the following:
@variables('str-api-key')

Here, ‘str-api-key’ was the name of the variable you set in the previous step (not the activity name, but the name of the variable.)

Dataflow parameter value mapped to the pipeline variable
Dataflow parameter value mapped to the pipeline variable

How to test the pipeline (step 7)

Run the pipeline and monitor the output. If everything is configured correctly, the dataflow will authenticate successfully:

The pipeline run history, showing a successful execution
The pipeline run history, showing a successful execution

However, if it does fail, check that the workspace identity does not have Key Vault permissions, and the parameter is not marked as ‘public’ in the dataflow. Also ensure that the dataflow wasn’t saved after enabling public parameters.

Finally, make sure the Key Vault URL includes ?api-version=7.4, and that the resource is set correctly.

Lessons learned (and notable quirks)

Public parameters in Gen2 dataflows are powerful but come with a few rough edges. Here’s everything I learned (the hard way!) to help you avoid making the same mistakes.

Public parameters must be explicitly enabled

It’s easy to create a parameter, assume it’s public, and then wonder why it’s not showing in the pipeline. You must open Options > Parameters, enable the public parameter toggle, and save the dataflow. These are crucial steps: skip any and the pipeline will not surface the parameter!

Required vs optional parameters really do matter

If you mark a parameter as required, the pipeline must supply a value or the run fails. If it’s optional, the dataflow falls back to its default value. I usually keep API secrets required – this way, the pipeline fails fast if the Key Vault step is misconfigured.

Secure output is helpful but not magic!

Enabling Secure Output and Secure Input on the activities masks the value of the secret in pipeline logs, which is good. However, once the value is inside the dataflow, it’s still a string. Do not write it to a table, or return it in a query result. Treat it as you would any other runtime credential.

Plain text may be a necessary evil during development

Walking through this process, you can imagine that debugging a dataflow by having to run a pipeline each time could be time consuming. I’ve found that putting the secret in the Power Query parameter temporarily allows me to test the dataflow. Just be careful to expire that secret when you’re ready to use the pipeline – and use a different secret for the pipeline than the one used for developing/debugging!

Additionally, I wouldn’t commit the Gen2 dataflow to Git (using Git Integration) until after you’ve put a placeholder value in the Power Query parameter. Otherwise, the secret gets stored in plain text in your repository, which is a security issue.

Conclusion

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 and out of source control.

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 never be logged or persisted.

Simple Talk is brought to you by Redgate Software

Take control of your databases with the trusted Database DevOps solutions provider. Automate with confidence, scale securely, and unlock growth through AI.
Discover how Redgate can help you

FAQs

1. Can I use Azure Key Vault secrets directly in a Gen1 dataflow?

No. Gen1 dataflows don’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 – requires a Gen2 dataflow, since only Gen2 supports parameters that a pipeline can override at execution time.

2. What permissions does my Fabric workspace need to access Key Vault?

The Fabric workspace needs its own managed identity (created under Workspace Settings > Workspace Identity), and that identity must be assigned the Key Vault Secrets User role in the vault’s Access Control (IAM) settings. Without this role assignment, the pipeline’s Web Activity will fail to retrieve the secret at runtime.

3. Should Gen2 dataflow parameters be required or optional?

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.

4. Does enabling Secure Output fully protect my API key in Fabric pipelines?

Secure Output and Secure Input hide the secret’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 – so it can still be exposed if written to a table or returned in a query result.

5. Is it safe to commit a Gen2 dataflow with public parameters to Git?

Yes, as long as the parameter’s default value is a non-sensitive placeholder before committing. If an actual API key is left in the Power Query parameter’s default value when the dataflow syncs through Fabric Git Integration, that secret will be stored in plain text in the repository.

This document contains proprietary information and is protected by copyright law.

Copyright © 2026 Red Gate Software Limited. All rights reserved

Article tags

About the author

John Kerski has over a decade of experience in technical and government leadership. He specializes in managing Data Analytics projects and implementing DataOps principles to enhance solution delivery and minimize errors. John's expertise is showcased through his ability to offer patterns and templates that streamline the adoption of DataOps with Microsoft Fabric and Power BI. His in-depth knowledge and hands-on approach provide clients with practical tools to achieve efficient and effective data operations. Throughout his career, John has dedicated himself to helping Federal Agencies and private sector clients maximize their use of Microsoft products. His extensive experience and certifications with Microsoft solutions ensure that his clients receive a high rate of return on their investments. Read John's blog at https://www.kerski.tech/.

John's contributions