A Secure Blazor Server Azure Deployment Pipeline
I wanted to kick off the year with something practical, modern, and production-ready. This post is based on my own experience deploying my new website, dotnetconsult.tech, using GitHub Actions into Azure App Service.
In this post, I’ll walk through how to set up a secure development and deployment flow using:
GitHub
GitHub Actions with OpenID Connect (OIDC)
This approach avoids stored secrets entirely and reflects how I now set up every new .NET project whether it’s for a client, a SaaS product, or an internal tool.
Why OpenID Connect (OIDC)?
-
✅ No publish profiles
-
✅ No long-lived secrets
-
✅ Short-lived tokens issued per deployment
-
✅ Azure-managed access control
-
✅ Enterprise-ready and future-proof
If you’re still using publish profiles or service principal secrets, this is the upgrade path.
Prerequisites
Before starting, you’ll need:
-
.NET SDK installed
-
Permissions to create:
Step 1 - Create the Blazor Server app
Step 2 — Push the project to GitHub
Because this is a brand-new project that hasn’t been added to source control yet:
-
Right-click the solution
-
Select Create Git Repository…
-
Select GitHub as the remote repository
-
Choose whether the repository should be Public or Private
-
Confirm or update the repository name
-
Optionally add a README
-
Click Create and Push
We’ve now created our sample application, set up a GitHub repository, and pushed the initial code.
Next, we’ll move on to publishing the application to Azure.
Step 3 - Create the Azure App Service
Open a browser and go to portal.azure.com
-
In the search bar, type App Services
-
Select App Services under Services
On the Basics tab, configure the following:
-
Subscription: Select your Azure subscription
-
Resource Group:
-
Choose an existing one, or
-
Click Create new
-
-
Name: Enter a unique app name
-
This becomes your URL:
https://<name>.azurewebsites.net
-
Publish: Code
-
Runtime stack: .NET 10 (LTS)
-
Operating System: Linux (Windows is also fine)
-
Region: Choose the closest region
Publish: Code
Runtime stack: .NET 10 (LTS)
Operating System: Linux (Windows is also fine)
Region: Choose the closest region
Pricing plan
-
Select an existing App Service Plan, or
-
Create a new one
For demos and testing, Free (F1) or Basic is sufficient.
Click Review + Create, then Create.
Once deployment completes, click Go to resource.
You’ll now see the App Service overview page, including:
-
Application URL
-
Status (Running)
At this point, the App Service is ready to receive deployments from GitHub Actions.
Step 4 — Create an Entra ID App Registration (OIDC)
- Name e.g. "github-actions-blazorsecureapp"
- Supported account types: Select Accounts in this organizational directory only
- Redirect URI: Leave this blank
- Application (client) ID
- Directory (tenant) ID
Step 5 — Assign permissions to Azure
Fill in the following:
-
Federated credential scenario:
GitHub Actions deploying Azure resources -
Organization:
Your GitHub organization or username -
Repository:
Your repository name -
Entity type:
Branch -
GitHub branch name:
main(or whichever branch triggers deployment) -
Name:
github-main-branch-deploy
Step 6 — Configure GitHub repository variables
To allow GitHub Actions to authenticate with Microsoft Azure, we need to store a few values securely as GitHub repository secrets.
These secrets will be used by the workflow at runtime and are never exposed in logs.
From your Microsoft Entra ID App Registration and Azure subscription, gather the following:
-
Application (Client) ID
-
Directory (Tenant) ID
-
Azure Subscription ID
Open Repository Settings
Open your repository on GitHub, Click Settings.
In the left-hand menu, expand Secrets and variables Select Actions
Add the Azure Secrets
Click New repository secret, Create the following secrets one by one:
Secret 1: AZURE_CLIENT_ID
-
Name:
AZURE_CLIENT_ID -
Value: Application (client) ID from the App Registration
-
Click Save secret
Secret 2: AZURE_TENANT_ID
-
Name:
AZURE_TENANT_ID -
Value: Directory (tenant) ID
-
Click Save secret
Secret 3: AZURE_SUBSCRIPTION_ID
-
Name:
AZURE_SUBSCRIPTION_ID -
Value: Your Azure subscription ID
-
Click Save secret
What These Secrets Are Used For
These secrets are referenced in your GitHub Actions workflow to:
-
Authenticate to Azure using OIDC
-
Select the correct tenant and subscription
-
Deploy your application to the correct App Service
No passwords or client secrets are required.
Step 7 — GitHub Actions workflow (OIDC)
Note: If you provisioned your App Service to be windows you will need to select "Azure App Service (Windows) "
.yml file and update:
Commit and Commit All and Push.
Step 8 — Deploy
What I’ll cover next
In upcoming posts on dotnetconsult.tech, I’ll be expanding this deployment pipeline into a full multi-environment setup, including:
-
Deploying to Azure App Service deployment slots (Dev, QA, Production)
-
Managing environment-specific configuration and app settings
-
Ensuring variables are scoped correctly per environment
-
Preventing configuration leakage between environments
-
-
Using GitHub Actions environments to control deployments
-
Implementing branch protection and promotion workflows:
-
Pull requests from Dev → QA
-
Pull requests from QA → Production
-
Production deployments only ever coming from QA
-
QA deployments only ever coming from Dev
-
-
Enforcing approval gates and checks before production releases
-
Designing CI/CD pipelines that reflect real-world enterprise release flows
The goal is to move from a single pipeline to a safe, auditable, and repeatable promotion model that scales from side projects to enterprise systems.
Final thoughts
Starting the year with a secure, modern deployment pipeline sets the tone for everything that follows.
If you’re building serious .NET applications in 2026, OIDC-based GitHub Actions + Azure should be your default.
If this article sparked ideas, raised questions, or you’d like to discuss how these concepts apply to your own projects, feel free to reach out via dotnetconsult.tech. I’m always happy to chat about real-world .NET architecture, performance, and design decisions.

Comments
Post a Comment