dotnet-monitor: Authentication and Egress Providers

dotnet-monitor: Authentication and Egress Providers

In a previous article, we introduced dotnet-monitor, a tool designed to collect diagnostic data via a REST API. However, to ensure its suitability for deployment in production environments, securing these endpoints is essential. As for large files like memory dumps, is there an alternative method to acquire them besides HTTP?

Authentication

So far, we have run dotnet-monitor locally by using a command similar to:

dotnet monitor collect --no-auth

Disabling authentication may be suitable for testing purposes; however, in a real environment, authenticated requests protect sensitive diagnostic data from unauthorized users. dotnet-monitor supports three authentication modes:

We will focus on the API Key mode, as it is the recommended one.

The API Key you use to secure dotnet-monitor is a secret JSON Web Token (JWT), cryptographically signed by a public/private key algorithm.

While this may appear complex, fortunately, we can generate these three values using a single dotnet-monitor command:

dotnet monitor generatekey

The output from this command will display a JWT token and the corresponding configuration. On Windows, the file settings should be located at %USERPROFILE%\.dotnet-monitor\settings.json. Update the file with the following content, or create it if it isn't present:

{
  "Authentication": {
    "MonitorApiKey": {
      "PublicKey": "{generated-public-key}",
      "Subject": "{generated-subject}"
    }
  }
}

Start dotnet-monitor using the following command:

dotnet monitor collect

Let's test the Process API using the following command:

curl --location 'https://localhost:52323/processes' --header 'Authorization: Bearer {generated-token}'

Egress Providers

The default method to egress diagnostic artifacts from dotnet-monitor is through HTTP. While this works well, it can become challenging for large artifacts and unreliable connections. dotnet-monitor lets us egress artifacts to other destinations, such as:

The APIs with egress provider support are dumps, gcdumps, traces, logs, and live metrics. Let's see the Filesystem egress provider. Update the settings file as follows:

{
  "Authentication": {
    "MonitorApiKey": {
      "PublicKey": "{generated-public-key}",
      "Subject": "{generated-subject}"
    }
  },
  "Egress": {
    "FileSystem": {
      "monitorFile": {
          "directoryPath": "/artifacts",
          "intermediateDirectoryPath": "/tempArtifacts"
      }
    }
  }
}

The directoryPath indicates the location where the data will be placed. The intermediateDirectoryPath indicates the location where data will initially be written. Then, the file will be renamed and moved to the directoryPath. Once configured, when triggering the artifact through an HTTP request, you can now specify which egress provider to use:

curl --location 'https://localhost:52323/trace?pid={pid}&egressProvider=monitorFile' --header 'Authorization: Bearer {generated-token}'

Ensure you have launched a .NET application and the pid corresponds to it. Time to see the Azure blob storage provider. Log into Azure by running az login, and create a storage account and container using the following commands:

az group create -l eastus -n MyResourceGroup
az storage account create --name 24f12674a14143d --resource-group MyResourceGroup --location eastus --sku Standard_ZRS --encryption-services blob
$assignee = az ad signed-in-user show --query objectId -o tsv
az role assignment create --role "Storage Blob Data Contributor" --assignee $assignee --scope "/subscriptions/e759b3f9-6ac3-4f9d-b479-1ba4471235cd/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/24f12674a14143d"
az storage container create --account-name 24f12674a14143d --name mycontainer --auth-mode login

Obtain the account keys by executing the following command:

az storage account keys list -g MyResourceGroup -n 24f12674a14143d

We can specify multiple egress providers through configuration. Update the settings file as follows:

{
  "Authentication": {
    "MonitorApiKey": {
      "PublicKey": "{generated-public-key}",
      "Subject": "{generated-subject}"
    }
  },
  "Egress": {
    "AzureBlobStorage": {
        "monitorBlob": {
            "accountUri": "https://24f12674a14143d.blob.core.windows.net/",
            "containerName": "mycontainer",
            "blobPrefix": "artifacts",
            "accountKey": "{account-key}"
        }
    },
    "FileSystem": {
      "monitorFile": {
          "directoryPath": "/artifacts",
          "intermediateDirectoryPath": "/tempArtifacts"
      }
    }
  }
}

With the configuration above, you can now make the following request:

curl --location 'https://localhost:52323/trace?pid=68992&egressProvider=monitorBlob' --header 'Authorization: Bearer {generated-token}'

We can check the generated artifact by listing all the blobs in the container:

az storage blob list --account-name 24f12674a14143d --container-name mycontainer --auth-mode login --output table

In summary, the article explains how to configure API Key authentication and use egress providers to transfer diagnostic artifacts to different destinations. Thank you, and happy coding.