microsoft / artifacts-credprovider

The Azure Artifacts Credential Provider enables dotnet, NuGet.exe, and MSBuild to interactively acquire credentials for Azure Artifacts feeds.
MIT License
759 stars 707 forks source link

Docker sample does not work on Windows #448

Closed JohnSchmeichel closed 3 months ago

JohnSchmeichel commented 1 year ago

Starting a new issue as a follow up from https://github.com/microsoft/artifacts-credprovider/issues/446 where the Windows docker sample does not work. When following the sample the docker build may end up with the error C:\app\dotnetapp.csproj : error NU1301: Unable to load the service index for source https://pkgs.dev.azure.com/<org>/<project>/_packaging/<feed>/nuget/v3/index.json.

For Windows Nano Server based images docker runs as ContainerUser by default, which is unable to install the credential provider as detailed in https://github.com/microsoft/artifacts-credprovider/issues/201. As a workaround the ContainerAdministrator user is used to install the credential provider, however doing so installs into the C:\Users\ContainerAdministrator\.nuget directory, which is not visible when the build later runs as ContainerUser. Hence the NuGet failures trying to load the service index.

Workarounds

Have few workarounds here until this can be fixed and the sample updated (note this issue only exists on Windows Nano Server containers as it runs as ContainerUser by default):

Option 1

Move the USER ContainerUser instruction after the RUN dotnet ... instructions. This runs the build as ContainerAdministrator which will be able to see and use the installed credential provider. This may or may not be desirable.

Option 2

Use the following docker instructions to grant the additional permissions required to run the credential provider script as ContainerUser. This also may not be desirable.

# Grant BUILTIN\Users access to read & delete from the TEMP directory
USER ContainerAdministrator
RUN & icacls C:\Windows\Temp\ /grant *S-1-5-32-545:'(OI)(CI)(RD,DE,DC)'
USER ContainerUser

# Install the cred provider
WORKDIR /Windows/Temp
RUN Invoke-WebRequest https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1 -OutFile installcredprovider.ps1; `
    .\installcredprovider.ps1; `
    del installcredprovider.ps1
JohnSchmeichel commented 1 year ago

As for a fix here, ideally the credential provider can be installed as ContainerUser without elevating, but there are a few unfortunate limitations here:

  1. The install script uses the TEMP env var (and .NET methods based off that) to create temporary files, but ContainerUser doesn't have any access to delete the temp files it creates (hence the icacls workaround to resolve this, granting read/delete permissions).
  2. On Nano Server there just isn't a good scratch location for temp files, so creating and cleaning up temp files needs to be done in the docker build itself.

The core problem imho is that these script-based install mechanisms leave a lot to be desired and run into these platform limitations both on capability and differences. Using a mechanism like the proposed https://github.com/NuGet/Home/issues/12567 would make all of these problems obsolete and allow the credential provider install to work cross-platform.

In the near term however, I'd propose the following changes to keep the spirit of the ContainerUser permission model (and the docker sample's goal of building within the container as a low-privileged account in a 2-phase build for isolation):

  1. Update the installcredprovider.ps1 script to allow an install path to be specified, falling back to TEMP if none is specified.
  2. Update the docker sample to install into a custom temp folder, such that it has full permissions to clean up after install.
JohnSchmeichel commented 1 year ago

Able to do this in the sample itself with https://github.com/dotnet/dotnet-docker/pull/4828

github-actions[bot] commented 9 months ago

This issue has had no activity in 90 days. Please comment if it is not actually stale.

embetten commented 9 months ago

not stale.

github-actions[bot] commented 6 months ago

This issue has had no activity in 90 days. Please comment if it is not actually stale.

JohnSchmeichel commented 6 months ago

maybe stale?

github-actions[bot] commented 3 months ago

This issue has had no activity in 90 days. Please comment if it is not actually stale.