Closed Astral100 closed 2 months ago
You are correct that RBAC and security is a weakness in our current Azure Cosmos DB documentation. There's work coming up in the next two months to rework these articles entirely. I'll follow up on this issue as we make progress.
@seesharprun Could you point me to the more relevant documentation though? Or explain what I should do to run the function locally with the same system-assigned principle id?
@Astral100 I'm going to assign this to the document author @seesharprun so he can take a look at it accordingly.
@Astral100, I am publishing an update to this article later today that will include steps on using RBAC to assign your local account permissions to access the data. Functionally, the steps will work like this:
az ad signed-in-user show --query "id"
az cosmosdb sql role assignment create \
--resource-group $resourceGroupName \
--account-name $cosmosName \
--role-definition-id "00000000-0000-0000-0000-000000000002" \
--principal-id "<your-principal-id>" \
--scope "/"
Long term, this article is being entirely replaced with a better article that spells out how to do this in minute detail. That documentation doesn't exist today.
I have long since solved this issue and forgotten about it :)
I don't remember exactly the solution, but the following code from my Setup class may help:
public static class SetupDi
{
public static void SetupDataAccessDi(this IServiceCollection services, HostBuilderContext hostContext)
{
var sqlDbConnectionString = hostContext.Configuration.GetSection(CoreConstants.AppSettingsConnectionStringKey).Value;
services.AddSingleton<ISqlDataAccess>(x => new SqlDataAccess(sqlDbConnectionString));
var isLocalDebugging = Environment.GetEnvironmentVariable("LocalDebugging") == "true";
services.AddSingleton<CosmosClient>(sp =>
{
var cosmosDbEndpoint = Environment.GetEnvironmentVariable("MyCosmosDb__accountEndpoint", EnvironmentVariableTarget.Process);
var credentials = isLocalDebugging ?
new DefaultAzureCredential(GetLocalCredentialOptions()) : // running locally
new DefaultAzureCredential(); // running on Azure
var options = new CosmosClientOptions()
{
AllowBulkExecution = true
};
if (isLocalDebugging)
{
options.ConnectionMode = ConnectionMode.Gateway;
}
return new CosmosClient(cosmosDbEndpoint, credentials, options);
});
services.AddSingleton<IUserDataRepository, UserDataRepository>();
services.AddSingleton<ICosmosDataAccess, CosmosDataAccess>();
}
private static DefaultAzureCredentialOptions GetLocalCredentialOptions()
{
return new DefaultAzureCredentialOptions()
{
ExcludeManagedIdentityCredential = true,
// ExcludeAzureCliCredential = true,
ExcludeAzureDeveloperCliCredential = true,
ExcludeAzurePowerShellCredential = true,
ExcludeEnvironmentCredential = true,
ExcludeInteractiveBrowserCredential = true,
ExcludeSharedTokenCacheCredential = true,
ExcludeVisualStudioCodeCredential = true,
ExcludeVisualStudioCredential = true,
ExcludeWorkloadIdentityCredential = true,
};
}
}
and
public class Program
{
public static void Main()
{
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureAppConfiguration(builder =>
{
builder.SetupReplicaServiceConfiguration();
})
.ConfigureServices((hostContext, services) =>
{
services.SetupReplicaServiceDi(hostContext);
})
.Build();
host.Run();
}
}
I also believe I granted the same permissions to my machine principal ID running the similar script from your post. Hope this can help
Under "(Optional) Run the function locally" section it only mentions that you need to setup
COSMOS_ENDPOINT
setting in yourlocal.settings.json
in order to run the function locally.This is wrong, because running function locally like this fails with
Request blocked by Auth <my cosmos account> : Request is blocked because principal [89c3cdb1-438c-4e04-a16d-...........] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts/readMetadata] on resource [/]
The principal id returned in this message is different from the principal id of my azure function.
I understand that my local account has a different principal Id from the system-assigned principle id in my function on Azure. However the document does not explain how to set the same system-assigned principle Id in my local environment and so I am unable to run the function locally.
Document Details
⚠ Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.