Hey, I am implementing logic that assigns roles in Azure Synapse Workspace. I have the following setup:
- Marketplace app that deploys resources to customer subscriptions (it has denied assignments)
- creates Azure Synapse Workspace
- creates managed Identity
- assigns managed identity Owner role in Azure Synapse Workspace
- Creates container app that will be hosting C# code that will update role assignments in synapse workspace
- adds manged identity to all resources so they can communicate with each other
After the marketplace app is installed I push the image of my C# app to the ACR and mount it in the Azure Container App.
The app has endpoint that calls service which updates role assignments in Azure Synapse Workspace. It has following steps
- Call endpoint on Azure Container App which will trigger service logic
- Set managed identity as an identity for assigning roles
- Call HttpClient or RoleAssgimentClient (Yeah both are failing) to assign the roles
I am getting 403 error every time even Managed Identity is set as the owner of the Synapse Workspace and should be able to assign roles like Synapse Administrator
P.S I tried to use https://management.azure.com/.default and https://dev.azuresynapse.net/ scopes
HTTP Client Code
public TokenCredential GetCredential(string tenantId = default)
{
if (string.IsNullOrEmpty(tenantId) is false)
{
return new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
TenantId = tenantId,
});
}
if (string.IsNullOrEmpty(EnvironmentVariables.ManagedIdentityClientId))
{
return new DefaultAzureCredential();
}
var credential = new DefaultAzureCredential(
new DefaultAzureCredentialOptions
{
ManagedIdentityClientId = EnvironmentVariables.ManagedIdentityClientId,
TenantId = EnvironmentVariables.TenantId,
});
return credential;
}
private async Task<string> GetAccessTokenAsync(CancellationToken cancellationToken)
{
var credential = credentialProvider.GetCredential();
var tokenRequestContext = new TokenRequestContext(
scopes: new[] { "https://management.azure.com/.default" }
);
var tokenRequest = await credential.GetTokenAsync(tokenRequestContext, cancellationToken);
logger.LogInformation(tokenRequest.Token);
return tokenRequest.Token;
}
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
string roleId = "6e4bf58a-b8e1-4cc3-bbf9-d73143322b78"; //Azure Synapse Administrator
var requestBody = new
{
roleId,
principalId = EnvironmentVariables.ManagedIdentityObjectPrincipalId,
scope = $"workspaces/{EnvironmentVariables.SynapseWorkspaceName}",
principalType = "ServicePrincipal"
};
var guid = Guid.NewGuid();
var jsonBody = JsonConvert.SerializeObject(requestBody);
var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
var url = $"https://{EnvironmentVariables.SynapseWorkspaceName}.dev.azuresynapse.net/roleAssignments/{guid}?api-version=2020-12-01";
var response = await httpClient.PutAsync(url, content, cancellationToken).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Role assignment created successfully.");
}
RoleAssignmentsClient code
public TokenCredential GetCredential(string tenantId = default)
{
if (string.IsNullOrEmpty(tenantId) is false)
{
return new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
TenantId = tenantId,
});
}
if (string.IsNullOrEmpty(EnvironmentVariables.ManagedIdentityClientId))
{
return new DefaultAzureCredential();
}
var credential = new DefaultAzureCredential(
new DefaultAzureCredentialOptions
{
ManagedIdentityClientId = EnvironmentVariables.ManagedIdentityClientId,
TenantId = EnvironmentVariables.TenantId,
});
return credential;
}
Guid principalId = new Guid(EnvironmentVariables.ManagedIdentityObjectPrincipalId);
Guid roleId = new Guid("6e4bf58a-b8e1-4cc3-bbf9-d73143322b78"); // Synapse Administrator
string endpointUrl = $"https://{EnvironmentVariables.SynapseWorkspaceName}.dev.azuresynapse.net";
var credential = credentialProvider.GetCredential();
var accessControlClient = new RoleAssignmentsClient(new Uri(endpointUrl), credential);
string roleAssignmentId = Guid.NewGuid().ToString();
string scope = $"workspaces/{EnvironmentVariables.SynapseWorkspaceName}";
var response = await accessControlClient.CreateRoleAssignmentAsync(
roleId: roleId,
principalId: principalId,
scope: scope,
roleAssignmentId: roleAssignmentId,
cancellationToken: cancellationToken);