Convert to workload identity federation
Tags: azure, devops, security
Published: 2024-03-27 10:27:31

If you tried to convert your service connection to use Federated Credentials, and the automatic conversion failed, don't "try again". You need to do it manually. 

![Automatic authentication conversion failed. ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/foc1rdc62rzhdvrs7r8n.png)

## The easiest approach that I found

### Permissions

First of all, you need to make sure you have enough permissions. According to the [documentation](https://learn.microsoft.com/en-us/azure/devops/pipelines/library/connect-to-azure?view=azure-devops#create-an-azure-resource-manager-service-connection-that-uses-workload-identity-federation), you must ensure that you are the Owner of the Azure Subscription used for the service connection.

That's not enough. Make sure you have <u>at least Global Reader</u>, too.

### The script

The easiest way to convert the connection manually is to run the

#### 
```bash
az ad app federated-credential create --id $appObjectId --parameters credential.json
```  
as described in [Handling Manual Conversions](https://github.com/devopsabcs-engineering/azure-devops-workload-identity-federation?tab=readme-ov-file#handling-manual-conversions).

The only tricky part is to update the `credential.json` correctly.

```json
{
    "name": "__ENDPOINT_ID__",
    "issuer": "https://vstoken.dev.azure.com/__ORGANIZATION_ID__",
    "subject": "sc://__ORGANIZATION_NAME__/__PROJECT_NAME__/__SERVICE_CONNECTION_NAME__",
    "description": "Federation for Service Connection __SERVICE_CONNECTION_NAME__ in https://dev.azure.com/__ORGANIZATION_NAME__/__PROJECT_NAME__/_settings/adminservices?resourceId=__ENDPOINT_ID__",
    "audiences": [
        "api://AzureADTokenExchange"
    ]
}
```

### __ENDPOINT_ID__
The issuer and subject are displayed in the "Authentication conversion" section, that appears after automatic conversion fails. The `__ENDPOINT_ID__`, however... you have to find it =)

Navigate to the https://dev.azure.com/{__ORGANIZATION_NAME__}/__PROJECT_NAME__/_apis/serviceendpoint/endpoints?authSchemes=ServicePrincipal&type=azurerm&includeFailed=false&includeDetails=true&api-version=7.1 to see a list of all the service connections that can be converted. 
Find the one you need, and copy the `id` - this is your `__ENDPOINT_ID__`.

```json
{
    "count": 1,
    "value": [
        {
            "data": {
                "environment": "AzureCloud",
                "scopeLevel": "Subscription",
                //...
            },
            "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            //...
            "authorization": {
                "parameters": {
                 	//...
                },
                "scheme": "ServicePrincipal"
            },
            "operationStatus": {
                "state": "Failed",
                "statusMessage": "converting_scheme_failed",
                "severity": null
            },
            "serviceEndpointProjectReferences": [
		//...
            ]
        }
    ]
}
```

### Done?

Maybe I should have waited longer... After checking my service connection again, I still saw the blue dot, and the "conversion failed" error. 

So I hit the "Try again" button again and.. lo and behold! It worked!