Skip to content

Docker Scout Reports Warning #655

Closed
Closed

Description

@moraekyle

Using an Azure DevOps build results in:

 1 warning found (use docker --debug to expand):
 - SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "FEED_ACCESS_TOKEN") (line 39)

I realize that this is the recommended way to use the ACP in a dockerfile. I just thought you might like to be aware that this warning now shows up when running a build.

Part of my build.yml

    - task: NuGetAuthenticate@1
      displayName: 'Authenticate to Azure Artifacts'
    - task: Docker@2
      displayName: 'Build Docker image'
      inputs:
        command: 'build'
        dockerfile: '$(setVars.dockerfile)'
        buildContext: '$(dockerBuildContext)'
        repository: '$(setVars.imageName)'
        tags: |
          dev-latest
          $(Build.SourceVersion)
        arguments: '--build-arg FEED_ACCESS_TOKEN=$(VSS_NUGET_ACCESSTOKEN)'

Relevant bits of my dockerfile

# Debug base: Debian for fast vsdbg performance (VS Fast Mode uses this)
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
RUN apt-get update && apt-get install -y --no-install-recommends wget \
    && rm -rf /var/lib/apt/lists/*
WORKDIR /app
EXPOSE 8080

# Runtime base: Alpine for dev/prod (small image size)
FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine AS base-alpine
RUN apk add --no-cache icu-libs tzdata ca-certificates
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src

# Install Azure Artifacts Credential Provider
RUN dotnet tool install --global Microsoft.Artifacts.CredentialProvider.NuGet.Tool --verbosity quiet
ENV PATH="${PATH}:/root/.dotnet/tools"

COPY --link ["Directory.Build.props", "."]
COPY --link ["nuget.config", "."]
COPY --link ["MyApp.csproj", "."]

# Set Azure Artifacts credentials as ARG (passed via --build-arg, safe in multi-stage build)
ARG FEED_ACCESS_TOKEN
ENV ARTIFACTS_CREDENTIALPROVIDER_EXTERNAL_FEED_ENDPOINTS="{\"endpointCredentials\":[{\"endpoint\":\"https://pkgs.dev.azure.com/__redacted__/nuget/v3/index.json\",\"password\":\"${FEED_ACCESS_TOKEN}\"}]}"

RUN dotnet restore "MyApp.csproj" -r linux-musl-x64
COPY --link . .
RUN dotnet build "./MyApp.csproj" -c $BUILD_CONFIGURATION -o /app/build /p:BuildingInsideDocker=true --no-restore

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN apk add --no-cache npm && npm install --prefix "./ClientApp" && npm run prod --prefix "./ClientApp"
RUN dotnet publish "./MyApp.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false -r linux-musl-x64 --self-contained false --no-restore

# Dev: Alpine with ca-certificates for local docker-compose (runs as root for update-ca-certificates)
FROM base-alpine AS dev
WORKDIR /app
COPY --link --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyApp.dll"]

# Final: Alpine minimal for cloud (non-root for security)
FROM dev AS final
USER $APP_UID

Activity

  1. embetten commented on Mar 11, 2026

    @embetten
    Contributor

    Do you mind reviewing and trying out the changes in #656 to see if that resolves the warning and allows you to build successfully? Thanks for the issue

  2. moraekyle commented on Mar 11, 2026

    @moraekyle
    Author

    I see now that you had a link to this sample file in the README.md, but it wasn't near as prominent as the link to https://github.com/dotnet/dotnet-docker/blob/main/documentation/scenarios/nuget-credentials.md#using-the-azure-artifact-credential-provider.

    I'll give this a try, but I think I've done something like this today, and I got away from it because it gave me warnings when I proceeded with dotnet build and dotnet publish. My AI tool suggested that was because dotnet build still invokes the nuget "path" even though I used --no-restore.

    Give me a few and I'll report back.

    UPDATE: Yeah, that's what I thought. It DOES work, sure. But I get this with the dotnet build but not dotnet publish commands:

    #21 [build 11/11] RUN dotnet build "./MyApp.csproj" -c Release -o /app/build /p:BuildingInsideDocker=true --no-restore
    #21 2.541 [NuGet Manager] [Warning]     [CredentialProvider]Warning: Cannot persist Microsoft authentication token cache securely!
    #21 2.542 [NuGet Manager] [Warning]     [CredentialProvider]Warning: Using plain-text fallback token cache
    #21 2.628 [NuGet Manager] [Warning] The plugin credential provider could not acquire credentials. Authentication may require manual action. Consider re-running the command with --interactive for `dotnet`, /p:NuGetInteractive="true" for MSBuild or removing the -NonInteractive switch for `NuGet`
    #21 2.643 [NuGet Manager] [Warning] The plugin credential provider could not acquire credentials. Authentication may require manual action. Consider re-running the command with --interactive for `dotnet`, /p:NuGetInteractive="true" for MSBuild or removing the -NonInteractive switch for `NuGet`
    #21 2.664 [NuGet Manager] [Warning] The plugin credential provider could not acquire credentials. Authentication may require manual action. Consider re-running the command with --interactive for `dotnet`, /p:NuGetInteractive="true" for MSBuild or removing the -NonInteractive switch for `NuGet`
    #21 2.677 [NuGet Manager] [Warning] The plugin credential provider could not acquire credentials. Authentication may require manual action. Consider re-running the command with --interactive for `dotnet`, /p:NuGetInteractive="true" for MSBuild or removing the -NonInteractive switch for `NuGet`
    #21 7.336   MyApp.Data -> /app/build/MyApp.Data.dll
    #21 10.49   MyApp -> /app/build/MyApp.dll
    #21 10.52
    #21 10.53 Build succeeded.
    #21 10.53     0 Warning(s)
    #21 10.53     0 Error(s)
    #21 10.53
    #21 10.53 Time Elapsed 00:00:09.56
    #21 DONE 11.3s
    
  3. embetten commented on Mar 12, 2026

    @embetten
    Contributor

    I just pushed updates to #656 which I tested locally and confirmed working.

    From the he plugin credential provider could not acquire credentials. ... messages I would assume the env variables are not being set correctly.

    A key difference in the pr changes the scope: export VSS_NUGET_URI_PREFIXES and export VSS_NUGET_ACCESSTOKEN (or ARTIFACTS_CREDENTIALPROVIDER_EXTERNAL_FEED_ENDPOINTS ) must be in the same RUN step as dotnet restore (and any other command that triggers a restore, like dotnet build or dotnet publish). Since they're exported rather than set via ENV, they only exist for that single RUN command.

  4. moraekyle commented on Mar 12, 2026

    @moraekyle
    Author

    I'll check tomorrow. Thank you. How does VSS_NUGET_URI_PREFIXES help with a specific NuGet feed in AzDO? In other words, how does it know the full URL for the feed?

    A couple other things:

    1. Should we use ARTIFACTS_CREDENTIALPROVIDER_URI_PREFIXES and ARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN instead?
    2. Will you be updating https://github.com/dotnet/dotnet-docker/blob/main/documentation/scenarios/nuget-credentials.md#using-the-azure-artifact-credential-provider or the README.md to more easily call out this sample?
    3. I just want to confirm you removed ARTIFACTS_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED.
  5. embetten commented on Mar 12, 2026

    @embetten
    Contributor

    In other words, how does it know the full URL for the feed?

    it does not - this change generalizes and simplifies the example. It basically says the credprovider will hand back the ARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN for any feed url that starts with https://pkgs.dev.azure.com which should be all ado feeds not using the legacy url. If you have multiple feeds with different identities or want to scope the token to a single feed ARTIFACTS_CREDENTIALPROVIDER_EXTERNAL_FEED_ENDPOINTS would be a better fit tbh.

    1. great call out - they are equivalent, but we are trying to move away from vss_ namin conventions updated the pr with ARTIFACTS_CREDENTIALPROVIDER prefix
    2. I will reach out to the team or follow up with a pr for the dotnet repo. But i did add a reference to our smaller sample in the readme as part of the pr
    3. yes, I did but on second thought I think we should disable them completely. see PR with updates

    Thanks for the feedback and collaboration - let me know your thoughts

  6. moraekyle commented on Mar 12, 2026

    @moraekyle
    Author

    TL;DR - If I use RUN --mount for both dotnet restore and dotnet publish, we're good to go. No warnings from Docker nor NuGet.

    embetten - I can't tell you how grateful I am for your quick and direct responses! You've taught me more in this thread about this provider than I could have understood from reading the docs.

    It looks like we'll have to do the RUN --mount for the dotnet build, too. I was hoping to avoid that (just because I feel like dockerfile is already too verbose), but oh well. Here's my final dockerfile that seems to work. (I'm still testing whether or not I care about the ACP caching disabled.)

    (I did add the ENV ARTIFACTS_CREDENTIALPROVIDER_URI_PREFIXES earlier to save a single line. 😄 )

    # ============================================================
    # BASE IMAGES
    # ============================================================
    # Debug base: Debian for fast vsdbg performance (VS Fast Mode uses this)
    FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
    RUN apt-get update && apt-get install -y --no-install-recommends wget \
        && rm -rf /var/lib/apt/lists/*
    WORKDIR /app
    EXPOSE 8080
    
    # Runtime base: Alpine for dev/prod (small image size)
    FROM mcr.microsoft.com/dotnet/aspnet:10.0-alpine AS base-alpine
    RUN apk add --no-cache icu-libs tzdata
    ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
    WORKDIR /app
    EXPOSE 8080
    
    # ============================================================
    # BUILD
    # ============================================================
    FROM mcr.microsoft.com/dotnet/sdk:10.0-alpine AS build
    ARG BUILD_CONFIGURATION=Release
    WORKDIR /src
    
    # Install Azure Artifacts Credential Provider
    ENV PATH="${PATH}:/root/.dotnet/tools"
    RUN dotnet tool install --global Microsoft.Artifacts.CredentialProvider.NuGet.Tool --verbosity quiet
    
    ENV ARTIFACTS_CREDENTIALPROVIDER_URI_PREFIXES="https://pkgs.dev.azure.com"
    ENV ARTIFACTS_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED=false
    ENV ARTIFACTS_CREDENTIALPROVIDER_MSAL_FILECACHE_ENABLED=false
    
    COPY --link ["Directory.Build.props", "."]
    COPY --link ["nuget.config", "."]
    COPY --link ["MyApp.Data/MyApp.Data.csproj", "MyApp.Data/"]
    COPY --link ["MyApp.Api/MyApp.Api.csproj", "MyApp.Api/"]
    
    # Restore
    RUN --mount=type=secret,id=nuget_token \
      export ARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN="$(cat /run/secrets/nuget_token)" && \
      dotnet restore "MyApp.Api/MyApp.Api.csproj" -r linux-musl-x64
    
    COPY --link . .
    WORKDIR "/src/MyApp.Api"
    
    # Build
    RUN --mount=type=secret,id=nuget_token \
      export ARTIFACTS_CREDENTIALPROVIDER_ACCESSTOKEN="$(cat /run/secrets/nuget_token)" && \
      dotnet build "./MyApp.Api.csproj" -c $BUILD_CONFIGURATION -o /app/build /p:BuildingInsideDocker=true --no-restore
    
    # ============================================================
    # PUBLISH
    # ============================================================
    FROM build AS publish
    ARG BUILD_CONFIGURATION=Release
    RUN dotnet publish "./MyApp.Api.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false -r linux-musl-x64 --self-contained false --no-restore
    
    # ============================================================
    # FINAL
    # ============================================================
    FROM base-alpine AS final
    WORKDIR /app
    COPY --link --from=publish /app/publish .
    USER $APP_UID
    ENTRYPOINT ["dotnet", "MyApp.Api.dll"]
  7. embetten commented on Mar 13, 2026

    @embetten
    Contributor

    closing - updated our repo sample with updated guidance. Will follow up with dockef

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions