Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for User Assigned Managed identity - CosmosDB NoSQL / Container Apps #1939

Open
1 task done
jmkelljr opened this issue Dec 20, 2023 · 3 comments
Open
1 task done
Assignees
Labels
backlog cosmos enhancement New feature or request

Comments

@jmkelljr
Copy link

What happened?

A bug happened!

Version

Microsoft.DataApiBuilder 0.9.7+e560142426d1c080b9fd7b7fabff51a276f6bf61

What database are you using?

CosmosDB NoSQL

What hosting model are you using?

Container Apps

Which API approach are you accessing DAB through?

GraphQL

Relevant log output

Please support RBAC Authentication for CosmosDB via a ManagedIdentity.  My company's security policies do not allow local authentication via keys.

I get the following error when trying to connect with the master key
{
  "errors": [
    {
      "message": "Response status code does not indicate success: Unauthorized (401); Substatus: 5202; ActivityId: ccfad820-3641-48e2-8808-8b0c3993f8f8; Reason: (Local Authorization is disabled. Use an AAD token to authorize all requests.\r\nActivityId: ccfad820-3641-48e2-8808-8b0c3993f8f8, Microsoft.Azure.Documents.Common/2.14.0, Linux/2.0 cosmos-netstandard-sdk/3.19.3);",
      "locations": [
        {
          "line": 2,
          "column": 5
        }
      ],
      "path": [
        "books"
      ]
    }
  ]
}

For more info see... 

https://joonasaijala.com/2021/07/01/how-to-using-managed-identities-to-access-cosmos-db-data-via-rbac-and-disabling-authentication-via-keys/

Code of Conduct

  • I agree to follow this project's Code of Conduct
@jmkelljr jmkelljr added bug Something isn't working triage issues to be triaged labels Dec 20, 2023
@jmkelljr
Copy link
Author

I realized that if I didn't specify the "AccountKey" parameter in the connection string that the code would drop into trying to connect with a managed identity. However, I am using a user-assigned managed identity and now have this issue:

fail: Azure.DataApiBuilder.Service.Startup[0]
A GraphQL request execution error occurred.
Azure.Identity.AuthenticationFailedException: ManagedIdentityCredential authentication failed: Service request failed.
Status: 400 (Bad Request)

  Content:
  {"statusCode":400,"message":"Unable to load the proper Managed Identity.","correlationId":"c4d8cdec-5a73-4a90-88f9-8b6fcef97dac"}
  
  Headers:
  Date: Wed, 20 Dec 2023 21:58:57 GMT
  Server: Kestrel
  Transfer-Encoding: chunked
  X-CORRELATION-ID: REDACTED
  Content-Type: application/json; charset=utf-8
  
  See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/managedidentitycredential/troubleshoot
   ---> Azure.RequestFailedException: Service request failed.
  Status: 400 (Bad Request)
  
  Content:
  {"statusCode":400,"message":"Unable to load the proper Managed Identity.","correlationId":"c4d8cdec-5a73-4a90-88f9-8b6fcef97dac"}
  
  Headers:
  Date: Wed, 20 Dec 2023 21:58:57 GMT
  Server: Kestrel
  Transfer-Encoding: chunked
  X-CORRELATION-ID: REDACTED
  Content-Type: application/json; charset=utf-8
  
     at Azure.Identity.ManagedIdentitySource.HandleResponseAsync(Boolean async, TokenRequestContext context, Response response, CancellationToken cancellationToken)
     at Azure.Identity.ManagedIdentitySource.AuthenticateAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)
     at Azure.Identity.ManagedIdentityClient.AuthenticateCoreAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)
     at Azure.Identity.ManagedIdentityClient.AppTokenProviderImpl(AppTokenProviderParameters parameters)
     at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.SendTokenRequestToAppTokenProviderAsync(ILoggerAdapter logger, CancellationToken cancellationToken)
     at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.GetAccessTokenAsync(CancellationToken cancellationToken, ILoggerAdapter logger)
     at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.ExecuteAsync(CancellationToken cancellationToken)
     at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
     at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenForClientParameters clientParameters, CancellationToken cancellationToken)
     at Azure.Identity.AbstractAcquireTokenParameterBuilderExtensions.ExecuteAsync[T](AbstractAcquireTokenParameterBuilder`1 builder, Boolean async, CancellationToken cancellationToken)
     at Azure.Identity.MsalConfidentialClient.AcquireTokenForClientCoreAsync(String[] scopes, String tenantId, Boolean enableCae, Boolean async, CancellationToken cancellationToken)
     at Azure.Identity.MsalConfidentialClient.AcquireTokenForClientAsync(String[] scopes, String tenantId, Boolean enableCae, Boolean async, CancellationToken cancellationToken)
     at Azure.Identity.ManagedIdentityClient.AuthenticateAsync(Boolean async, TokenRequestContext context, CancellationToken cancellationToken)
     at Azure.Identity.ManagedIdentityCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)
     --- End of inner exception stack trace ---
     at Microsoft.Azure.Cosmos.Routing.GlobalEndpointManager.GetAccountPropertiesHelper.GetAccountPropertiesAsync()
     at Microsoft.Azure.Cosmos.GatewayAccountReader.InitializeReaderAsync()
     at Microsoft.Azure.Cosmos.CosmosAccountServiceConfiguration.InitializeAsync()
     at Microsoft.Azure.Cosmos.DocumentClient.InitializeGatewayConfigurationReaderAsync()
     at Microsoft.Azure.Cosmos.DocumentClient.GetInitializationTaskAsync(IStoreClientFactory storeClientFactory)
     at Microsoft.Azure.Cosmos.DocumentClient.EnsureValidClientAsync(ITrace trace)
     at Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler.EnsureValidClientAsync(RequestMessage request, ITrace trace)
     at Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler.SendAsync(RequestMessage request, CancellationToken cancellationToken)
     at Microsoft.Azure.Cosmos.Handlers.RequestInvokerHandler.SendAsync(String resourceUriString, ResourceType resourceType, OperationType operationType, RequestOptions requestOptions, ContainerInternal cosmosContainerCore, FeedRange feedRange, Stream streamPayload, Action`1 requestEnricher, ITrace trace, CancellationToken cancellationToken)
     at Microsoft.Azure.Cosmos.ContainerCore.ReadContainerAsync(ITrace trace, ContainerRequestOptions requestOptions, CancellationToken cancellationToken)
     at Microsoft.Azure.Cosmos.ClientContextCore.RunWithDiagnosticsHelperAsync[TResult](ITrace trace, Func`2 task)
     at Microsoft.Azure.Cosmos.ClientContextCore.OperationHelperWithRootTraceAsync[TResult](String operationName, RequestOptions requestOptions, Func`2 task, TraceComponent traceComponent, TraceLevel traceLevel)
     at Azure.DataApiBuilder.Core.Resolvers.CosmosQueryEngine.GetPartitionKeyPath(Container container, ISqlMetadataProvider metadataStoreProvider) in /src/src/Core/Resolvers/CosmosQueryEngine.cs:line 267
     at Azure.DataApiBuilder.Core.Resolvers.CosmosQueryEngine.GetIdAndPartitionKey(IDictionary`2 parameters, Container container, CosmosQueryStructure structure, ISqlMetadataProvider metadataStoreProvider) in /src/src/Core/Resolvers/CosmosQueryEngine.cs:line 278
     at Azure.DataApiBuilder.Core.Resolvers.CosmosQueryEngine.ExecuteAsync(IMiddlewareContext context, IDictionary`2 parameters, String dataSourceName) in /src/src/Core/Resolvers/CosmosQueryEngine.cs:line 72
     at Azure.DataApiBuilder.Core.Services.ResolverMiddleware.InvokeAsync(IMiddlewareContext context) in /src/src/Core/Services/ResolverMiddleware.cs:line 106
     at HotChocolate.Utilities.MiddlewareCompiler`1.ExpressionHelper.AwaitTaskHelper(Task task)
     at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)
     at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)

info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'Hot Chocolate GraphQL Pipeline'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 POST http://graphqlapp.nicesky-e371e381.eastus2.azurecontainerapps.io/graphql application/json 117 - 500 - application/json;+charset=utf-8 68.6274ms

It appears this is a known issue with SDK's in Azure Container Apps as referenced here:

microsoft/azure-container-apps#442

You may need to modify how you are getting the credential to allow for the config file to specify the AZURE_CLIENT_ID

@seantleonard
Copy link
Contributor

Thank you for raising this issue. We are tracking this ask via #1944. Currently, only system assigned managed identities are supported.

@seantleonard seantleonard added duplicate This issue or pull request already exists enhancement New feature or request backlog and removed bug Something isn't working triage issues to be triaged duplicate This issue or pull request already exists labels Jan 2, 2024
@seantleonard seantleonard changed the title [Bug]: Support for User Assigned Managed identity - CosmosDB NoSQL / Container Apps Jan 2, 2024
@dgcaron
Copy link

dgcaron commented Sep 27, 2024

we are actually using a user assigened managed identity and this does work. you need to specify the clientid in an environment variable called AZURE_CLIENT_ID in the container apps app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog cosmos enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants