You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 8fcd59b
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: src/services/identity-guide-service.ts
+74-48Lines changed: 74 additions & 48 deletions
Original file line number
Diff line number
Diff line change
@@ -160,40 +160,51 @@ Test the authentication by running a workflow manually or pushing to main branch
160
160
\`\`\`powershell
161
161
$SUBSCRIPTION_ID = "${subscriptionId}"
162
162
$RESOURCE_GROUP = "${resourceGroup}"
163
-
$APP_NAME = "apiops-azdo-sp"
163
+
$MI_NAME = "apiops-azdo-mi"
164
+
$MI_RESOURCE_GROUP = "<your-mi-resource-group>"
164
165
$ENVIRONMENTS = @(${environmentsArrayPowerShell})
165
166
\`\`\`
166
167
167
168
**Git Bash:**
168
169
\`\`\`bash
169
170
SUBSCRIPTION_ID="${subscriptionId}"
170
171
RESOURCE_GROUP="${resourceGroup}"
171
-
APP_NAME="apiops-azdo-sp"
172
+
MI_NAME="apiops-azdo-mi"
173
+
MI_RESOURCE_GROUP="<your-mi-resource-group>"
172
174
ENVIRONMENTS=(${environmentsArrayBash})
173
175
\`\`\`
174
176
175
177
---
176
178
177
-
## Step 2: Create Service Principal
179
+
## Step 2: Create Managed Identity
178
180
179
181
**PowerShell:**
180
182
\`\`\`powershell
181
-
$SP_OUTPUT = az ad sp create-for-rbac --name $APP_NAME --role "API Management Service Contributor" --scopes "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP"
182
-
$spObj = $SP_OUTPUT | ConvertFrom-Json
183
-
$APP_ID = $spObj.appId
184
-
$PASSWORD = $spObj.password
185
-
$TENANT_ID = $spObj.tenant
183
+
# Create user-assigned managed identity (no password)
184
+
az identity create --name $MI_NAME --resource-group $MI_RESOURCE_GROUP
185
+
$MI_CLIENT_ID = az identity show --name $MI_NAME --resource-group $MI_RESOURCE_GROUP --query clientId -o tsv
186
+
$MI_PRINCIPAL_ID = az identity show --name $MI_NAME --resource-group $MI_RESOURCE_GROUP --query principalId -o tsv
187
+
$TENANT_ID = az account show --query tenantId -o tsv
Write-Host "Managed Identity Principal ID: $MI_PRINCIPAL_ID"
190
+
191
+
# Assign API Management Service Contributor role
192
+
az role assignment create --assignee-object-id $MI_PRINCIPAL_ID --assignee-principal-type ServicePrincipal --role "API Management Service Contributor" --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP"
186
193
\`\`\`
187
194
188
-
**Git Bash:** (use \`MSYS_NO_PATHCONV=1\` to prevent path conversion on Windows)
195
+
**Git Bash:**
189
196
\`\`\`bash
190
-
SP_OUTPUT=$(MSYS_NO_PATHCONV=1 az ad sp create-for-rbac --name "$APP_NAME" --role "API Management Service Contributor" --scopes "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP")
TENANT_ID=$(az account show --query tenantId -o tsv)
202
+
echo "Managed Identity Client ID: $MI_CLIENT_ID"
203
+
echo "Managed Identity Principal ID: $MI_PRINCIPAL_ID"
195
204
196
-
**Important:** The password is only shown once during creation. Save it securely now!
205
+
# Assign API Management Service Contributor role
206
+
az role assignment create --assignee-object-id "$MI_PRINCIPAL_ID" --assignee-principal-type ServicePrincipal --role "API Management Service Contributor" --scope "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP"
207
+
\`\`\`
197
208
198
209
---
199
210
@@ -230,52 +241,67 @@ SUBSCRIPTION_NAME=$(az account show --subscription "$SUBSCRIPTION_ID" --query na
230
241
231
242
## Step 4: Create Azure Service Connections
232
243
233
-
Set the service principal key for non-interactive creation:
244
+
Create service connections using workload identity federation:
| \`ORG_NAME\` | Short organization name (for Build Service) | \`my-org\` |
152
146
| \`AZDO_PROJECT\` | Azure DevOps project name | \`apim-project\` |
153
147
${envGatherTable}
154
148
155
149
---
156
150
157
-
## Step 2 — Create Service Principal
151
+
## Step 2 — Create Managed Identity
158
152
159
-
> ⚠️ **Error Handling:** If any command fails, stop immediately and show the user the full error output verbatim. Do NOT retry silently. Common issues include insufficient permissions (requires Contributor role on the subscription or resource group).
153
+
> ⚠️ **Error Handling:** If any command fails, stop immediately and show the user the full error output verbatim. Do NOT retry silently. Common issues include insufficient permissions (requires Contributor role on the resource group).
160
154
161
155
\`\`\`bash
162
-
# Create service principal with API Management Service Contributor role
163
-
SP_OUTPUT=$(az ad sp create-for-rbac \\
164
-
--name "\${APP_NAME}" \\
156
+
# Create user-assigned managed identity (no password — credentials-free)
> **Note:** The password (client secret) is displayed only once. You'll use it in the next step to create service connections, then it will be securely stored in Azure DevOps.
178
+
> **Note:** User-assigned managed identities have no passwords or secrets. The RBAC role is assigned using the managed identity's principal ID, not a client ID.
178
179
179
180
---
180
181
@@ -195,25 +196,70 @@ SUBSCRIPTION_NAME=$(az account show --subscription "\${SUBSCRIPTION_ID}" --query
195
196
196
197
## Step 4 — Create Service Connections
197
198
198
-
> ⚠️ **Security Note:** The service principal password is set via environment variable and cleared immediately after creating service connections.
199
+
> ⚠️ **Note:** Workload identity federation means Azure DevOps exchanges its own OIDC token for an Azure token at runtime — no stored secrets. Creating a WIF service connection is a two-step process: create the connection (which generates an issuer/subject), then create a federated credential on the managed identity.
200
+
201
+
The function below handles both steps. Call it once for each service connection:
199
202
200
203
\`\`\`bash
201
-
# Set the service principal password as environment variable
0 commit comments