Implementing a health check - How can I check whether communication with the Auth0 Management API works?

I’m integrating Auth0 in a Blazor Web Application (target framework net8.0), where I’m currently implementing an /account/register page where a user can create an account by entering given_name, family_name, email and password.

The app’s backend handles submit of this form (uses "connection":"Username-Password-Authentication") and connects to the Auth0 Management API to create the user. To send the necessary HTTP request, I’m using Auth0.ManagementApi.IManagementApiClient.Users.CreateAsync(UserCreateRequest) from NuGet package Auth0.ManagementApi version 7.25.1.

When I integrate third-party services in our software, I usually implement a ‘health check’ which asserts whether communication with the service succeeds. This health check is usually a simple test, asserting that the configuration (client_id, client_secret, etc.) is correct, and returns “Healthy” when communication works; otherwise, “Unhealthy”.

I’d like to implement this for our Auth0 Management API integration as well.

Using the mentioned NuGet package, how can I assert that the app’s configuration (client_id, client_secret, etc.) is correct and can be used to make API calls?

For now, I’m fetching the list of users (limiting page size to 1), but I don’t really need the user’s data here. Also, this call doesn’t assert whether the Auth0 M2M application was assigned the required create:users scope (which my app needs to create users when handling the /account/register form submit).

How could I assert these things? Perhaps there’s an endpoint available to test scopes / permissions?

Thanks in avance for your guidance!

Hi @stevenvolckaert

Welcome to the Auth0 Community!

Thank you for posting your question. Implementing a health check for your app is a great idea for ensuring that your application’s configuration and permissions are correct. We have a separate Docs page about Monitor Applications.

In terms of your request, you should check get grants endpoint → Auth0 Management API v2

It will allow you to health check the system, your configuration, and the permissions of your app.

I hope it will help you
Thanks
Dawid

Thank you @dawid.matuszczyk for your help.

I am able to get retrieve grants, but each grant seems to contain the scopes attached (granted?) to each user in the tenant. This is not the information I’m looking for.

I have two Auth0 apps confgured in the tenant:

  1. A Regular Web App, which allows users to authenticate with the Blazor Web Application;
  2. A Machine to Machine app, which is used by our ASP.NET Core backend to create users.

The M2M app is configured like so:

As you can see, permissions read:users and create:users are enabled on the Auth0 Management API.

From our ASP.NET Core backend, how can I assert that these permissions are set?

Asserting read:users can be done by reading users, of course, but to test create:users, it seems I would have to create a ‘fake’ or ‘dummy’ user, and see whether calling the endpoint throws an ApiException.

Is there any other way?

Thanks again,
Steven Volckaert

I have found the solution which is as follows:

  1. Use Auth0.ManagementApi.IManagementApiClient.ClientGrants.GetAllAsync(new GetClientGrantsRequest { ClientId = "Your_M2M_App_client-id" });
  2. Search the list for the client grant that matches the Grant ID found in the API tab of the M2M App:

  1. Check whether the required scopes are a subset of the List<string> ClientGrant.Scopes property using HashSet<string>.IsSubsetOf(ClientGrant.Scopes):
public static IReadOnlySet<string> RequiredScopes { get; set; } = new HashSet<string> { "create:users" };

public async Task<HealthCheckResult> CheckHealthAsync(
    HealthCheckContext context,
    CancellationToken cancellationToken = default)
{
    var getClientGrantsRequest = new GetClientGrantsRequest
    {
        ClientId = this.auth0Settings.ManagementApiClientId
    };

    var operationName =
        $"{this.clientGrantsClient.GetType()}.{nameof(this.clientGrantsClient.GetAllAsync)}("
      + $"{nameof(GetClientGrantsRequest)} " + new { getClientGrantsRequest.ClientId }
      + ", CancellationToken)";

    try
    {
        var clientGrantsList = await this.clientGrantsClient.GetAllAsync(
            request: getClientGrantsRequest,
            cancellationToken: cancellationToken
        );

        var clientGrant = clientGrantsList.FirstOrDefault(
            x => x.Id == this.auth0Settings.ManagementApiClientGrantId
        );

        if (clientGrant is null)
            return new HealthCheckResult
            (
                status: context.Registration.FailureStatus,
                description: $"Client grant '{this.auth0Settings.ManagementApiClientGrantId}' "
                           + $"not found in client '{this.auth0Settings.ManagementApiClientId}'."
            );

        return RequiredScopes.IsSubsetOf(clientGrant.Scope)
            ? HealthCheckResult.Healthy()
            : new HealthCheckResult
            (
                status: context.Registration.FailureStatus,
                description: $"Client grant '{this.auth0Settings.ManagementApiClientGrantId}' has scopes "
                           + $"{clientGrant.Scope.ToJsonString()}; expected scopes {RequiredScopes.ToJsonString()}."
            );
    }
    catch (ApiException exception)
    {
        return new HealthCheckResult
        (
            status: context.Registration.FailureStatus,
            description: exception.GetErrorMessageForFailedOperation(operationName),
            exception: exception
        );
    }
}```

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.