Skip to content

Improve push failure error message for API key package ID scope mismatch#10775

Open
Copilot wants to merge 2 commits intodevfrom
copilot/improve-push-failure-error-message
Open

Improve push failure error message for API key package ID scope mismatch#10775
Copilot wants to merge 2 commits intodevfrom
copilot/improve-push-failure-error-message

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 13, 2026

When an API key's package ID scope doesn't match the package being pushed, users receive the same generic 403 as invalid/expired keys — making the root cause impossible to self-diagnose.

  • Add ApiKeyNotAuthorized_PackageIdScopeMismatch string resource with a descriptive message about the package ID scope
  • Add IsPackageIdScopeMismatch property to ApiScopeEvaluationResult, set to true only when at least one scope allows the requested action but no scope's subject pattern matches the package ID — ensuring the specific message is shown only for genuine package-ID scope mismatches, not action mismatches
  • Populate IsPackageIdScopeMismatch in ApiScopeEvaluator.Evaluate by checking whether any scope allows the requested action regardless of subject; guards against null requestedActions
  • In GetHttpResultFromFailedApiScopeEvaluationHelper, check result.IsPackageIdScopeMismatch (instead of the broader !result.ScopesAreValid) to return the specific message only when the package ID is the failing dimension
  • Update InvalidScopes_Data test fixture to cover both isPackageIdScopeMismatch: true (specific message) and isPackageIdScopeMismatch: false (generic message) cases
  • Add SetsIsPackageIdScopeMismatchWhenSubjectDoesNotMatchButActionDoes test to ApiScopeEvaluatorFacts
  • Update lodash from ^4.17.21^4.18.0 (resolves to 4.18.1); run npm audit fix to remove nested vulnerable lodash 4.17.23 instances in globule/grunt-legacy-* transitive deps (GHSA-r5fr-rjxr-66jc)

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines:
1 pipeline(s) require an authorized user to comment /azp run to run.

1 similar comment
@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines:
1 pipeline(s) require an authorized user to comment /azp run to run.

Copilot AI changed the title [WIP] Improve push failure error message Improve push failure error message for API key package ID scope mismatch Apr 13, 2026
Copilot AI requested a review from chabiss April 13, 2026 20:29
@chabiss chabiss marked this pull request as ready for review April 17, 2026 01:25
@chabiss chabiss requested a review from a team as a code owner April 17, 2026 01:25

string message;
if (result.PermissionsCheckResult == PermissionsCheckResult.Allowed && !result.IsOwnerConfirmed)
if (!result.ScopesAreValid)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this message appropriate for all cases when ScopesAreValid is false?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot question for you above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No — ScopesAreValid is false whenever matchingScope == null, which covers both a package-ID mismatch and an action mismatch (e.g., a PackageUnlist-scoped key used to push). In the action-mismatch case the package-ID message would be misleading.

Fixed in d54d492 by adding an IsPackageIdScopeMismatch property to ApiScopeEvaluationResult. It's set to true only when at least one scope already allows the requested action — meaning the subject (package ID) is specifically what failed. The controller now checks result.IsPackageIdScopeMismatch instead of !result.ScopesAreValid, so the specific message is shown only for genuine package-ID scope mismatches and the generic message is shown for action mismatches.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With help of copilot, looking at the code, I can see two cases:

  1. Package ID scope mismatch: the API key's Scope.Subject pattern doesn't match the package ID.
  2. Action scope mismatch: the API key's Scope.AllowedAction doesn't include the requested action (e.g., the key only allows "unlist" but the user is trying to "push").

Maybe the message should be

"The specified API key does not have permission to perform this action on this package. The API key may have a package ID scope that does not include this package ID, or it may not allow the requested action."

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 17, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 1javsblobprodcus364.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
  • 6s7vsblobprodcus313.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
    • Triggering command: /usr/bin/dotnet dotnet build src/NuGetGallery.Services/NuGetGallery.Services.csproj -collect-logs (dns block)
  • dlbvsblobprodcus316.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
  • k0ivsblobprodcus356.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
  • st8vsblobprodcus339.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
  • u6ovsblobprodcus377.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
  • x3yvsblobprodcus370.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
  • xupvsblobprodcus332.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
    • Triggering command: /usr/bin/dotnet dotnet build src/NuGetGallery.Services/NuGetGallery.Services.csproj -collect-logs (dns block)
  • yttvsblobprodcus357.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)
  • ytvvsblobprodcus310.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet build tests/NuGetGallery.Facts/NuGetGallery.Facts.csproj ger.cs tricCall.cs verHttpClientHandler.cs ckage.cs sAccessConditionHelperTests.cs sTokenCacheFacts.cs actory.cs ccessTokenCache.cs SqlConnectionStringBuilderFacts.cs onne�� SqlConnectionFactoryFacts.cs icense/LicenseTests.cs ndor/bin/git ader (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from joelverhagen April 17, 2026 17:46
@chabiss chabiss force-pushed the copilot/improve-push-failure-error-message branch from d54d492 to b2952a9 Compare April 17, 2026 17:56
@chabiss chabiss changed the base branch from main to dev April 17, 2026 18:28
@chabiss chabiss force-pushed the copilot/improve-push-failure-error-message branch from b2952a9 to 36ae755 Compare April 17, 2026 18:31
Broaden the message to cover action mismatches in addition to package ID scope mismatches.

Co-authored-by: Copilot <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[NuGet.org Bug]: Improve push failure error message

3 participants