# dotnet-monitor: Authentication and Egress Providers

In a previous [article](https://blog.raulnq.com/diagnostic-net-apps-using-dotnet-monitor), 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:

```powershell
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:

* [API Key](https://github.com/dotnet/dotnet-monitor/blob/main/documentation/authentication.md#api-key-authentication)
    
* [Azure Active Directory](https://github.com/dotnet/dotnet-monitor/blob/main/documentation/authentication.md#azure-active-directory-authentication)
    
* [Windows](https://github.com/dotnet/dotnet-monitor/blob/main/documentation/authentication.md#windows-authentication)
    

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:

```powershell
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:

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

Start `dotnet-monitor` using the following command:

```powershell
dotnet monitor collect
```

Let's test the [Process API](https://github.com/dotnet/dotnet-monitor/blob/main/documentation/api/processes.md) using the following command:

```powershell
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:

* [Filesystem](https://github.com/dotnet/dotnet-monitor/blob/main/documentation/configuration/egress-configuration.md#azure-blob-storage-egress-provider)
    
* [Azure blob storage](https://github.com/dotnet/dotnet-monitor/blob/main/documentation/configuration/egress-configuration.md#80-s3-storage-egress-provider)
    
* [S3 storage](https://github.com/dotnet/dotnet-monitor/blob/main/documentation/configuration/egress-configuration.md#filesystem-egress-provider)
    

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:

```json
{
  "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:

```powershell
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:

```powershell
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:

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

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

```json
{
  "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:

```powershell
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:

```powershell
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.
