NuGet with Azure Artifacts - Host Rule Implementation
This article details the instructions to successfully configure our repo integrations with your NuGet private registries that are hosted in Azure Artifacts. NuGet private registries can be accessed by authentication via an Azure Personal Access Token (PAT). This will allow our repo integrations to scan your private NuGet packages for vulnerabilities and compliance.
Generating a Personal Access Token (PAT) in Azure for your Artifacts feed
If you do not have a Personal Access Token (PAT) generated for your Artifacts feed, you can follow the instructions laid out in Azure’s documentation on NuGet Artifacts.
Note: The PAT that is created must have Read & write permissions for the Packaging Scope.
Encrypting your Azure PAT
For Mend-Hosted repo integrations (Github.com and Azure Repos)
Navigate to Mend's Repository Integration Secrets Encryption page
Each secret you encrypt must be scoped to a Github org or Azure project and its use will be restricted to those within the app. There are the following fields on the encryption page:
Organization/Group - required; your Github org or your Azure project to which secrets are to be scoped
Repository - optional; your Github or Azure repository to which secrets are to be scoped. If you specify this field then other repositories in the Github org or Azure project will not be able to access the private registry.
Raw value - required; your Azure PAT that was created earlier
Click on Encrypt. This will create an encrypted value, which is the result of the encryption to be used in the integration
Copy this encrypted value
For Self-Hosted repo integrations (Github Enterprise, Bitbucket Server/Data Center/Cloud, and Gitlab)
Follow the steps outlined below to generate encryption for each of the Self-Hosted repo integrations:
Mend for GitHub Enterprise | Handling Private Registries and Authenticated Repositories
Installing Mend for GitLab | Handling Private Registries and Authenticated Repositories
When generating a secret, there are the following fields on the encryption page:
Organization\Group - required; your GitHub org, GitLab group, or Bitbucket group to which secrets are to be scoped
Repository - optional; your repository to which secrets are to be scoped
Raw value - required; your Azure PAT that was created earlier
Click on Encrypt. This will create an encrypted value, which is the result of the encryption to be used in the integration
Copy this encrypted value and save it for the step, Applying the hostRules
Where can I find the matchHost URL for NuGet?
The URL that is to be used for the matchHost setting in the hostRules can be found by following the steps below:
Navigate to your Azure Project where the Artifact feed is located and click on Artifacts in the left-hand tree.
In this screen, click on Connect to Feed:
Find and click on NuGet.exe:
Within the Project setup step, copy the URL within the
<packageSources>
block. This will be the matchHost URL that you will use in your hostRules:
Note: If you have multiple Azure Artifact feeds for your NuGet packages, you will need to complete these steps and create a hostRule for each feed that is being used.
Applying the hostRules
Within your repo-config.json (if you have a global setup) or, in your .whitesource file (if you are configuring at the repo level), include the following required hostRules settings:
matchHost - The URL of the Azure Artifacts feed where your NuGet packages are located. NOTE: You should have one hostRule for each Azure Artifacts feed where your NuGet packages are located - meaning there can be multiple hostRules
If your feed is Org-scoped, the URL will look something like this:
CODEhttps://pkgs.dev.azure.com/<AzureOrgName>/_packaging/<AzureFeedName>/nuget/v3/index.json
If your feed is Project-scoped, the URL will look something like this:
CODEhttps://pkgs.dev.azure.com/<AzureOrgName>/<AzureProjectName>/_packaging/<AzureFeedName>/nuget/v3/index.json
hostType -
nuget
userName - Your Azure Organization name or your Azure Project name, depending on how your Artifacts feed was scoped when it was created. You can also check this value in your nuget.config’s
<packageSources>
block.token - The encrypted value that was generated
hostRules Examples
Example with an Org-scoped Artifacts feed:
{
"hostRules": [
{
"matchHost": "https://pkgs.dev.azure.com/<AzureOrgName>/_packaging/<AzureFeedName>/nuget/v3/index.json",
"hostType": "nuget",
"userName": "<Azure Organization name>",
"encrypted": {
"token": "3f832f2983yf89hsd98ahadsjfasdfjaslf............"
}
}
]
}
Example with a Project-scoped Artifacts feed:
{
"hostRules": [
{
"matchHost": "https://pkgs.dev.azure.com/<AzureOrgName>/<AzureProjectName>/_packaging/<AzureFeedName>/nuget/v3/index.json",
"hostType": "nuget",
"userName": "<Azure Project name>",
"encrypted": {
"token": "3f832f2983yf89hsd98ahadsjfasdfjaslf............"
}
}
]
}
Keeping Your Internal Packages up to Date with Renovate
If you are storing internal dependencies in your Azure Artifact feed, you can use Mend Renovate to create pull requests that will keep those dependencies up to date. In your .whitesource file, enable Renovate with the following configuration:
"remediateSettings": {
"enableRenovate":true,
"workflowRules": {
"enabled": false
}
}
By default renovate will create 2 pull requests an hour and allow for 10 concurrent pull requests to be open. To bypass these constraints, add “prConcurrentLimit”:0 and “prHourLimit”:0 to the configuration above.
A second host rule will need to be added to allow Renovate to access the packages in your feed.
The matchHost will change to just include your org name, and the encrypted key should be password instead of token. The encrypted key used will be the same.
{
"hostRules": [
{ // Host rule to allow Scanner to access packages
"matchHost": "https://pkgs.dev.azure.com/<AzureOrgName>/<AzureProjectName>/_packaging/<AzureFeedName>/nuget/v3/index.json",
"hostType": "nuget",
"userName": "<Azure Project name>",
"encrypted": {
"token": "3f832f2983yf89hsd98ahadsjfasdfjaslf............"
}
},
{ // Host Rule to allow Renovate to access packages
"matchHost": "https://pkgs.dev.azure.com/<AzureOrgName>/",
"hostType": "nuget",
"userName": "<Azure Project name>",
"encrypted": {
"password": "3f832f2983yf89hsd98ahadsjfasdfjaslf............"
}
}
]
}