Skip to main content
Skip table of contents

Mend for Bitbucket Data Center - Private Registries and Authenticated Repositories

Handling Private Registries and Authenticated Repositories

Private registries hosted on any platform that can be accessed with credentials are supported (Nexus, GitHub, Artifactory, Azure Artifacts, GitLab, NPM)

Supported languages and package managers:

  • NPM

  • Yarn

  • Maven

  • Gradle

  • Pip

  • Pipenv

  • Go

  • Nuget

  • Ruby

  • SBT

In order to scan dependencies from private registries and authenticated repositories, Mend must be provided with credentials, such as an NPM token. These credentials must be added as encrypted secrets to the .whitesource file, either per-repository or in the shared global config, if the secret scope is org-wide.

Сreate the encrypted secrets. Each secret you encrypt must be scoped to a Bitbucket group or repository and use of it will be restricted to those within the app.

  1. Use GPG to generate a PGP Key. Use the command gpg --full-generate-key and follow the prompts to generate a key. Please note that at this time we do not support using a passphrase for decryption, so it is best to generate the keys without a passphrase. Name and email are not important.

    1. Copy the key ID from the output or run gpg --list-secret-keys if you forgot to take a copy. This is your public key.

    2. Run gpg --armor --export-secret-keys YOUR_NEW_KEY_ID > ws-private-key.asc to generate an armored (text-based) private key file

    3. Run gpg --armor --export YOUR_NEW_KEY_ID > ws-public-key.asc to generate an armored (text-based) public key file

  2. Provide the private key to the Controller, Remediate, and Scanner with environmental variable (learn more about environmental variables in the Advanced Technical Information documentation). There are two options for how to do it, but only one option should be used.

    1. WS_HOST_RULES_PRIVATE_KEY - the value of the private key itself.

      1. Please note, that the private key should be formatted to work properly:

        1. Remove the beginning and end comments (as well as any extra lines).

        2. At the end of the key, remove the buffer text. It is usually 5 characters long and looks like the example below:

        3. Remove all of the new lines in the key so it is all in one line (i.e. delete all \n characters).

    2. WS_HOST_RULES_PRIVATE_KEY_FILE_PATH - path to the file containing the private key. This file should be mapped to the running containers.

  3. Open wss-encryption/secret-encryption.html in your favorite editor.

  4. Find and replace the text "COPY_YOUR_PUBLIC_PGP_KEY_HERE" with your newly generated public key and save the file.
    const publicKeyString = `COPY_YOUR_PUBLIC_PGP_KEY_HERE`;

  5. Generate a secret. There are the following fields on the encryption page:

    1. Organization\Group - required, your Bitbucket group to which tokens secret be scoped.

    2. Repository - optional, your Bitbucket repository to which secret should be scoped.

    3. Raw value - required, confidential values/secrets such as tokens or passwords.

    4. Encrypted value - the result of the encryption to be used in the integration.

  6. After the secret is created, please add it to the hostRules parameter of the .whitesource file.

index-enterprise.html

Example of hostRules:

CODE
{
  "hostRules": [
    {
      "matchHost": "registry.npmjs.org",
      "hostType": "npm",
      "userName": "bot1",
      "encrypted": {
        "token": "3f832f2983yf89hsd98ahadsjfasdfjaslf............"
      }
    },
    {
      "matchHost": "https://custom.registry.company.com/maven/",
      "hostType": "maven",
      "userName": "bot1",
      "encrypted": {
        "password": "p278djfdsi9832jnfdshufwji2r389fdskj........."
      }
    }
  ]
}

Additional notes

  • Copy the entire output of the key generator including comments to paste into the string.

    i.e. include "-----BEGIN PGP PUBLIC KEY BLOCK-----..."

  • The string uses javascript backticks and not quotes. This is to allow a multi-line string so that you do not have to replace any line breaks with new-line characters. Be aware of any auto indenting by your editor that may introduce spaces to the public key and cause encryption to fail.

  • We use asymmetric public-key cryptography of the PGP methodology. Organization/Group, Repository, Raw Value - all information you provide on the encryption page is secured with this approach.

  • Notes for NPM private registries:

    • To connect to private registries the https://docs.npmjs.com/cli/v8/configuring-npm/npmrc file of the scanned project is used. It is either edited (hostRules from the config are applied) or created for scanning purposes.

    • If .npmrc is missing and only one host is used in the project it should be connected to the official http://npmjs.com . Otherwise, only private dependencies will be scanned and all public dependencies of this registry will be omitted.

    • If several hosts are used in the project it is required that .npmrc file exists in the project and contains information about these hosts.

  • Notes for Yarn private registries:

    • For Yarn 1 projects, to connect to private registries the .npmrc file of the scanned project is used. For Yarn 2/3 .yarnrc is used. It is either edited (hostRules from the config are applied) or created for scanning purposes.

    • If .yarnrc is missing (or npmRegistryServer in it is not set) and only one host is used in the project - it will be set to the hostRules.matchHost from the config. In the same case, if several hosts are used, npmRegistryServer will be set to https://registry.yarnpkg.com.

  • Notes for Maven private registries:

    • To connect to private registries the settings.xml file of the scanned project is used. It is either edited (hostRules from the config are applied) or created for scanning purposes.

  • Notes for Gradle private registries:

    • To connect to private registries the build.gradle or settings.gradle file of the scanned project is used. For both of these files, we also support the kotlin (.kts) format.

    • The buildscript or pluginManagement blocks need to be at the beginning of the build.gradle or settings.gradle respectively.

    • matchHost should contain the full path to the private registries, not just the domain.

  • Notes for Nuget private registries:

    • To connect to private registries the NuGet.Config file of the scanned project is used. It is either edited (hostRules from the config are applied) or created for scanning purposes.

  • Notes for Pip private registries:

    • Certain special characters are not valid in the credential part of a URL. If the user or password part of the login credentials contains any of these special characters then they must be percent-encoded.

  • Notes for Pipenv private registries:

    • Use either envVariablesMapping or sourceName when setting host rules.

  • Notes for Go private registries:

    • To connect to private registries the .netrc file of the scanned project is used. It is either edited (hostRules from the config are applied) or created for scanning purposes.

    • Only HTTPS is available for matchHost, HTTP is not supported.

    • If the private registry is hosted on GitHub, only token can be used in the encrypted (i.e., password is not supported).

Automate Secret Encryption for Private Registries

You can encrypt secrets from the CLI, using the curl, echo, jq, gpg, grep and tr CLI programs.
Here is an example:

CODE
curl https://app.renovatebot.com/renovate.pgp --output renovate.pgp
echo -n '{"o":"your-organization", "r":"your-repository (optional)", "v":"your-secret-value"}' | jq . -c | gpg --encrypt -a --recipient-file renovate.pgp | grep -v '^----' | tr -d '\n'

The above script uses:

  • curl to download the Mend Renovate hosted app's public key

  • echo to echo a JSON object into jq

  • jq to validate the JSON and then compact it

  • gpg to encrypt the contents

  • grep and tr to extract the encrypted payload which we will use

The jq step is optional, you can leave it out if you wish. Its primary value is validating that the string you echo to gpg is valid JSON and compact.

Note: Encrypted secrets must have at least an org/group scope, and optionally a repository scope. This means that Renovate will check if a secret's scope matches the current repository before applying it, and warn/discard if there is a mismatch.

Encrypted secrets usually have a single organization. But you may encrypt a secret with more than one organization, for example, org1,org2. This way the secret can be used in both the org1 and org2 organizations.

For more information on how to use secrets for private packages, refer to the Private package support documentation.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.