0
votes

I have created a build definition in Team Services which needs to run on a private agent (i.e. on-premise build server). This agent is running under a domain account. I then created a NuGet feed in Team Services to which I am trying to publish a package created by the NuGet Packager task.

I am getting an authentication error (403 Forbidden) when trying to push a package to the internal feed using the NuGet Publisher Task (NuGet v4.0.0.2283) :

2017-05-04T21:05:06.3076014Z CredentialProvider.TeamBuild: Failed to authenticate to https://mycompany.pkgs.visualstudio.com/_packaging/MyProject/nuget/v3/index.json from your project collection, prefix = https://mycompany.pkgs.visualstudio.com/
2017-05-04T21:05:07.8546075Z System.AggregateException: One or more errors occurred. ---> NuGet.Protocol.Core.Types.FatalProtocolException: Unable to load the service index for source https://mycompany.pkgs.visualstudio.com/_packaging/MyProject/nuget/v3/index.json. ---> System.Net.Http.HttpRequestException: Response status code does not indicate success: 403 (Forbidden).

Please note that I am able to publish the same package manually on the build server using my credentials as decribed here : https://www.visualstudio.com/en-us/docs/package/nuget/nuget-exe

Now, the build definition is project scoped (not Project Collection scoped). Therefore, the default permissions which add the Project Collection Build Service account to the contributors of the feed is probably incorrect. I believe the Project Build Service account associated with this specific team project needs to be added to the contributors (or owners).

Since there are 15+ projects in this Team Services account and the Project Build Service accounts all have the same name, finding the correct account requires some work. I managed to find the specific Project Build Service account guid by addding the following PowerShell inline script to the build (which I got from here : https://github.com/Microsoft/vsts-tasks/issues/3287):

$headers = @{Authorization="Bearer ${env:SYSTEM_ACCESSTOKEN}"}
$response = Invoke-RestMethod "${env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}/_apis/connectionData" -Headers $headers 
$response.authenticatedUser | Format-List id, customDisplayName | Out-Host

Now, I cannot seem to add the Project Build Service account to the contributors of the feed, either by typing its guid or by typing "Project Build Service" to find the one with the correct guid from the list of accounts.

Is this a bug or did I forget to configure something ?

1
What's the build result if you add your account as owners for in feed permissions?Marina Liu
My (user) account is already an owner of the feed. That is probably why I am able to publish to the feed manually using the VSTS Credentials Provider. The agent service is running under a different (service) account though. Do I need to create a user for this service account in VSTS ? I didn't see a requirement to do this in the MSDN documentation...Vincent G

1 Answers

3
votes

I managed to find a solution. For the benefit of others who might have the same problem, here what was done to solve the issue.

I started looking at the REST API for feed permissions to try adding the project specific build service account (using the id gathered from the PowerShell script described above) to the feed's contributors.

Looking at the API documentation , I realized that you need to specify the full identity descriptor which has the following format :

Microsoft.TeamFoundation.ServiceIdentity;00000000-0000-0000-0000-000000000000:Build:10000000-0000-0000-0000-00000000000 

I then modified the inline PowerShell script to display all the information about the Project Build Service identity :

$headers = @{Authorization="Bearer ${env:SYSTEM_ACCESSTOKEN}"}
$response = Invoke-RestMethod "${env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI}/_apis/connectionData" -Headers $headers 
$response.authenticatedUser | Format-List | Out-Host

I then realized that the descriptor returned contains a second guid that appears after the "Build:" part which is different than the identity id. This guid also appears in the providerDisplayName property of the authenticatedUser object returned.

Using the feed permissions interface, I tried to do a search using the providerDisplayName guid and finally got one result ! After adding this Project Build service account to the contributors and running a new build, I was able to publish the feed.

To facilitate the configuration of permissions of the feed, I believe the documentation specific to build identities could be improved as it only mentions project collection scoped build definitions and not project scoped definitions.

Ultimately, the problem stems from the fact that if a Team Services account countains multiple projects, giving the correct permissions to the project's build service account is not easy since they all have the same name, i.e. Project Build Service (account).