DEV Community

Marco Platzer
Marco Platzer

Posted on

Using PowerShell to Create Service Principals for RBAC

In this blog post, I’ll guide you through the process of creating a service principal using PowerShell, including steps for retrieving secrets and leveraging federated credentials as well as certificate-based authentication for secure, secretless authentication in workflows like GitHub Actions. Managing programmatic access to your Azure resources securely is essential, and a service principal is a key part of achieving that.

Prerequisites

Before we start, ensure you have:

  • PowerShell installed on your machine.
  • The Az PowerShell module installed.
  • An Azure account with sufficient permissions to create service principals and assign roles.

Creating a Service Principal Using PowerShell

To create a service principal with PowerShell, start by running the following command:

$sp = New-AzADServicePrincipal -DisplayName "Quickstart App Service API" -Role "Contributor" -Scope "/subscriptions/<YourSubscriptionID>"
Enter fullscreen mode Exit fullscreen mode
  • Replace the DisplayName with the name you want for your service principal.
  • Replace <YourSubscriptionID> with your Azure subscription ID.

This command will create the service principal, assigning it the Contributor role at the subscription level, and return details such as the application ID (client ID) and tenant ID.

Retrieving the Client Secret After Creation

After creating your service principal, you can retrieve the client secret with a simple command:

$sp.PasswordCredentials.SecretText
Enter fullscreen mode Exit fullscreen mode

This command outputs the client secret value, which is crucial for authenticating the service principal. Remember to securely store this secret, as it will not be retrievable later.

Using Federated Credentials for GitHub Actions Workflows

To avoid managing client secrets directly, you can use federated credentials for secure, passwordless authentication, especially useful in CI/CD workflows. Federated credentials allow a service principal to authenticate with Azure Active Directory through an external identity provider, such as GitHub.

Here's how you can configure federated credentials for your service principal:

$params = @{
    ApplicationObjectId = (Get-AzADApplication -DisplayName "Quickstart App Service API").Id
    Audience = "api://AzureADTokenExchange"
    Issuer = "https://token.actions.githubusercontent.com"
    Name = "OIDC"
    Subject = "repo:<GitHubOrg>/<RepoName>:environment:<EnvironmentName>"
}

New-AzADAppFederatedCredential @params
Enter fullscreen mode Exit fullscreen mode

Replace the placeholders:

  • <GitHubOrg> with your GitHub organization name.
  • <RepoName> with your GitHub repository name.
  • <EnvironmentName> with the specific environment in GitHub Actions (e.g., production, staging

This configuration allows GitHub Actions workflows to authenticate without storing a client secret, enhancing security by leveraging OpenID Connect (OIDC) for token exchange.

To make the federated credential setup even more flexible, you can specify different types of entities as the subject in the federated credentials, such as GitHub branches, pull requests, or tags. This flexibility allows you to restrict or target specific actions in your GitHub repository, enhancing control over which workflows can authenticate with Azure.

Branch-Based Authentication: The subject pattern repo:<GitHubOrg>/<RepoName>:ref:refs/heads/<BranchName> restricts authentication to workflows triggered on a specific branch.

Pull Request-Based Authentication: Using repo:<GitHubOrg>/<RepoName>:pull_request enables authentication specifically for pull requests within the repository, useful for CI/CD testing workflows.

Tag-Based Authentication: The pattern repo:<GitHubOrg>/<RepoName>:ref:refs/tags/<TagName> allows authentication for workflows triggered by specific tags, often used for versioned deployments.

Certificate-Based Authentication

This approach offers a secure way to authenticate Azure applications and workflows, especially when compared to traditional methods like password-based authentication. Certificates can be easily regenerated when expired and work well for automation scenarios.

Generate a Self-Signed Certificate

The first step is to create a self-signed certificate in your local certificate store. Below is the PowerShell snippet to achieve this:

$certconf = @{
    CertStoreLocation = "cert:\CurrentUser\My"
    Subject = "CN=myWorkflow"
    KeySpec = "KeyExchange"
}

# Generate a self-signed certificate
$cert = New-SelfSignedCertificate @certconf
Enter fullscreen mode Exit fullscreen mode

This script creates a certificate with the subject CN=myWorkflow. The certificate is stored in the CurrentUser store under My.

Convert Certificate to Base64

Azure requires the certificate in Base64 format. You can achieve this using the following command:

# Convert certificate to Base64 for storing in the service principal
$keyValue = [System.Convert]::ToBase64String($cert.GetRawCertData())
Enter fullscreen mode Exit fullscreen mode

This extracts the raw data from the certificate and encodes it as a Base64 string.

Create the Service Principal

With the Base64 certificate ready, configure and create the Service Principal:

# Configure Service Principal
$spconf = @{
    DisplayName = "myWorkflow"
    CertValue   = $keyValue
    EndDate     = $cert.NotAfter
    StartDate   = $cert.NotBefore
}

# Create the Azure AD Service Principal
$sp = New-AzADServicePrincipal @spconf
Enter fullscreen mode Exit fullscreen mode

This command creates a Service Principal with the Base64-encoded certificate as its authentication method.

Assign Roles to the Service Principal

New-AzRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $sp.AppId -Scope "/subscriptions/YOUR_SUBSCRIPTION_ID/resourceGroups/YOUR_RG/providers/Microsoft.ContainerRegistry/registries/YOUR_ACR"
Enter fullscreen mode Exit fullscreen mode

This script grants the Contributor role to the Service Principal on a specific Azure Container Registry.

Full Script

By following these steps, you’ll be able to create service principals in Azure using PowerShell and set up secretless authentication for secure, automated workflows in environments like GitHub Actions. Using federated credentials can streamline your automation workflows, making them both efficient and secure.

Top comments (0)