0

I get an 401 error if I try to use my private npm registry in Azure DevOps. My configuration looks like this:

# pipeline.yaml (repo root folder)
steps:
  - task: npmAuthenticate@0
    inputs:
      workingFile: .npmrc
  - script: |
      git config --global user.email 'bot@renovateapp.com'
      git config --global user.name 'Renovate Bot'
      npx --userconfig .npmrc renovate
    env:
      TOKEN: $(System.AccessToken)
      PAT: $(PAT)
# config.js (repo root folder)
module.exports = {
    platform: 'azure',
    endpoint: 'https://devops.<url>.de/.../',
    logLevel: 'debug',
    token: process.env.TOKEN,
    repositories: ['...'],
    enabledManagers: ["npm"],
    hostRules: [
        {
            enabled: true,
            hostType: 'npm',
            matchHost: 'devops.<url>.de',
            token: process.env.PAT,
        },
    ],
};
# .npmrc (repo root folder)
registry=https://devops.<url>.de/Collaboration/_packaging/.../npm/registry/
always-auth=true

The installation of renovate works and my registry get used for it. But renovate itself runs into a 401. How can I tell renovate to use the .npmrc generated from the `npmAuthenticate@0` task?

Error stack:

ERROR: Repository has unknown error (repository=...)
       "err": {
         "statusCode": 401,
         "message": "Failed request: (401)",
         "stack": "Error: Failed request: (401)\n    at RestClient.<anonymous> (/root/.npm/_npx/05eeecd92f4e18e0/node_modules/typed-rest-client/RestClient.js:202:31)\n    at Generator.next (<anonymous>)\n    at fulfilled (/root/.npm/_npx/05eeecd92f4e18e0/node_modules/typed-rest-client/RestClient.js:6:58)\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)"
       }
rene
  • 3
  • 3

2 Answers2

0

The renovate command will modify the repo you defined in the config.js file(e.g. repositories: ['...']).

Since you are using the $(System.AccessToken) as authentication method, you need to grant Contribute permissions (e.g. Contribute,Contribute to pull requests,Create branch ) of target repo to the corresponding build service account.

Project Level Build Service Account Name: Your-project-name Build Service (your-collection-name)

Organization Level Build Service Account Name: Project Collection Build Service (your-collection-name)

You can navigate to Project Settings -> Repositories -> Target Repo -> Security and grant the Contribute permission to the two build service account.

For example:

enter image description here

For more detailed info, you can refer to this doc: Manage build service account permissions

On the other hand, if you need to update the repo from another project. You need to disable the option: Limit job authorization scope to current project for non-release pipelines in Project Settings -> Settings.

Kevin Lu-MSFT
  • 20,786
  • 3
  • 19
  • 28
  • Thanks for the detailed reply. I have set ever permission now which makes possible sense. Unfortunately I still get an 401 error from renovate bot. I also created a project level npm feed and tried it with this one as well without luck. Do you have any idea how to pass the token to renovate bot and tell him to use it? Do I need to do it with the `npmrc` config option in the config.js file or over the `npmToken` option or over the `hostRules`option? Or better over the `config.npmrc` file in the repo folder? Or a combination of this options? – rene Dec 03 '22 at 11:58
  • @rene The step you used to pass the token should be correct. You can try to use the PAT of your account and check if it can work. In this case, we can narrow down this issue to check if it is related to the permission of the build service account. ` TOKEN: $(PATofyouraccount)` – Kevin Lu-MSFT Dec 05 '22 at 03:06
  • Thanks for your replay again. I edited my post so you can see how I pass the PAT to renovate. Unfortunately it still results in a 401. I also added the error stack to the post. What I noticed, if I try to use my PAT to login to the npm registry from a bash, it will not work as token. I can only make it work by username/password and passing the token then as password. Logging in the same way to renovate with username/password doesn't work. – rene Dec 05 '22 at 09:07
  • @rene have you tried to disable the option in **project settings -> settings**, Limit job authorization scope to current project for non-release pipelines ? – Kevin Lu-MSFT Dec 05 '22 at 09:13
  • I checked under Project settings -> pipeline settings, everything is disabled there, also `Limit job authorization scope to current project for non-release pipelines` – rene Dec 05 '22 at 09:23
  • Can you help confirm that if the repo defined in the config.js is in the same project as pipeline? – Kevin Lu-MSFT Dec 05 '22 at 09:25
  • Yes I can confirm it. Renovate bot is also able to create a branch and a pull request in my repo. The only thing what isn't working is the connection to the npm feed. – rene Dec 05 '22 at 09:29
  • To connect to the npm feed, can you go to azure feed -> Settings -> permission to grant the Contributor role to the Build service account? And can you point out which part in the config.js file will access npm feed. Then I can do further test – Kevin Lu-MSFT Dec 05 '22 at 09:31
  • I can confirm that the build service has the Contributor role and my account with the PAT has the Owner role. – rene Dec 05 '22 at 09:41
  • @rene Can you change matchHost to `matchHost: 'pkgs.dev.azure.com'` in config.js? Please check if it can work. Expected npm registry url sample: `https://pkgs.dev.azure.com/orgname/projectname/_packaging/feedname/npm/registry/ ` Refer to this doc: https://docs.renovatebot.com/modules/platform/azure/ – Kevin Lu-MSFT Dec 05 '22 at 10:02
  • I created my config after this documentation. I tried it this way as well. I changed it now to: `https://///_packaging//npm/registry/`. This doesn't work either. – rene Dec 05 '22 at 10:34
  • I managed to get rid of the 401 by using the PAT in combination with username/password auth. Now I run into a 403 error when renovate tries to create the branch: `You need the Git 'GenericContribute' permission to perform this action. Details: identity Build\\043e2d93-b5....`. Do you know where I can set `GenericContribute` for the `System.AccessToken`? Are this the permissions you showed in your screenshot above? I did set this permissions. – rene Dec 05 '22 at 13:35
  • 1
    I finally managed to solve the problem. I experimented with a few more settings in the config.js and finally made it work. – rene Dec 05 '22 at 20:41
  • 1
    @rene would you mind sharing what settings in the **config.js** you've changed to make it work? – Bagata Jan 10 '23 at 13:48
0

It seems that the official renovate docs for azure devops with a private feed isn't correct. This works for me:

Give the pipeline "Build User" contribute permissions on the feed: Azure Devops Artifacts -> Settings -> Permissions -> Add the user/service that runs the pipeline with contributor.

azure-pipelines.yml

schedules:
  - cron: '0 3 * * *'
    displayName: 'Every day at 3am'
    branches:
      include: [main]
    always: true

trigger: none

pool:
  vmImage: ubuntu-latest

steps:
  - task: npmAuthenticate@0
    inputs:
      workingFile: .npmrc

  - bash: |
      git config --global user.email 'bot@renovateapp.com'
      git config --global user.name 'Renovate Bot'
      npx --userconfig .npmrc renovate
    env:
      LOG_LEVEL: DEBUG
      TOKEN: $(System.AccessToken)
      RENOVATE_TOKEN: AZURE_DEVOPS_PAT_TOKEN_HERE
      GITHUB_COM_TOKEN: REPLACEME

config.js

The important part here is to not use "pkgs.dev.azure.com" as the matchHost value, instead you can see in the debug logs if the feed is different on the 401'd requests, in my case it's "ORG_NAME_LOWERCASED.pkgs.visualstudio.com".

const repositories = require("./repositories");

// Security token used by the running build
const pipelineToken = process.env.TOKEN;
const patTokenForFeed = process.env.RENOVATE_TOKEN;

module.exports = {
  platform: "azure",
  endpoint: "https://dev.azure.com/ORG_NAME/",
  token: pipelineToken,
  hostRules: [
    {
      hostType: "npm",
      matchHost: "ORG_NAME_LOWERCASED.pkgs.visualstudio.com",
      username: "apikey",
      password: patTokenForFeed,
    },
  ],
  repositories
};


.npmrc

registry=https://pkgs.dev.azure.com/ORG_NAME/PROJECT_NAME/_packaging/FEED_NAME/npm/registry/
always-auth=true
Sauceman
  • 147
  • 6