Package signing is an important part of a secure .NET software supply chain. It helps teams verify that a package was signed by an expected publisher and that the package has not been modified after signing.

However, certificate changes can create an unexpected problem for teams that use strict NuGet trusted signer policies.

A package can still be legitimate, available from the expected source, and correctly signed, while a local or CI policy rejects it because the signing certificate no longer matches the certificate or rule that the organization trusts.

This is why a certificate change should be treated as a policy compatibility issue, not simply as a certificate renewal.

In this article, we will look at how NuGet trusted signers work, why certificate changes can affect package restoration, how to identify the problem, and how to update a policy without weakening package verification.

What Is NuGet Package Signing?

NuGet package signing uses digital signatures to provide authenticity and integrity information for packages.

A signed package contains signature information that can be validated during package operations.

At a high level, the process looks like this:

Package
   |
   v
Digital signature
   |
   v
Certificate chain
   |
   v
Trusted publisher
   |
   v
Package validation

The certificate is part of the trust relationship.

If your organization has configured NuGet to accept packages only from specific trusted signers, a change in the signing certificate can affect whether a package is accepted.

What Is a Trusted Signer?

NuGet supports trusted signer configuration through the NuGet configuration system.

A trusted signer policy can define which certificates or repositories are trusted.

For example, a configuration can contain rules similar to:

<configuration>
  <config>
    <add key="signatureValidationMode" value="require" />
  </config>

  <trustedSigners>
    <author name="ExamplePublisher">
      <certificate fingerprint="ABC123..." hashAlgorithm="SHA256" />
    </author>
  </trustedSigners>
</configuration>

The exact configuration should match the signing model and certificate information used by your organization.

The important point is that the policy is not simply saying:

Trust this package name.

It can be enforcing a much stronger condition:

Trust packages signed by this expected signer or certificate.

That distinction becomes important when certificates change.

Why a Certificate Change Can Break CI

Suppose your CI pipeline currently trusts certificate A:

Trusted certificate
        |
        v
Certificate A

A package publisher later changes its signing certificate:

Old certificate
Certificate A

New certificate
Certificate B

The package is still signed, but your policy may still expect:

Certificate A

The validation result can therefore become:

Package signature
       |
       v
Certificate B
       |
       v
Trusted policy expects Certificate A
       |
       v
Validation fails

This is an expected consequence of strict certificate-based trust.

It does not automatically mean that the package is malicious or that the new certificate is unsafe.

It means your trust policy and the publisher's current signing identity no longer match.

Certificate Rotation Is Different From Package Tampering

This distinction is important when troubleshooting.

A failed signature validation can result from several different situations.

For example:

Situation

Possible Result

Trusted certificate matches

Package accepted

Valid package, new certificate not trusted

Validation failure

Invalid signature

Validation failure

Package modified after signing

Validation failure

Incorrect trust configuration

Validation failure

Certificate chain problem

Validation failure

Therefore, do not immediately disable signature validation when a package restore fails.

First determine why validation failed.

What Is a Certificate Fingerprint?

A certificate fingerprint is a hash-based identifier for a certificate.

For example:

ABCDEF1234567890...

The fingerprint is useful because a certificate can be identified without storing the entire certificate in a configuration file.

A trusted signer policy may therefore contain something conceptually similar to:

<certificate
    fingerprint="ABCDEF..."
    hashAlgorithm="SHA256" />

If the publisher starts signing with a different certificate, the fingerprint changes.

Your existing policy may then stop matching.

Why Exact Certificate Trust Is Useful

Certificate-specific trust can provide strong control over package consumption.

For example, an organization may want to prevent a package from being accepted simply because someone publishes a package using the same package identity.

A certificate rule provides an additional trust boundary.

This can be especially useful for organizations with strict software supply-chain requirements.

However, strict trust also creates maintenance work.

Certificate rotation is one example.

What Happens During a Certificate Rotation?

Consider this simplified lifecycle:

Old certificate
      |
      v
Packages signed with old certificate
      |
      v
Certificate rotation
      |
      v
New certificate
      |
      v
New package releases

Your CI environment may contain:

Trusted certificate = Old certificate

The publisher may now produce:

Package signed by = New certificate

The result is a mismatch.

The package can therefore fail validation even though the package itself is from the expected publisher.

How to Identify a Trust Policy Failure

Start with the package restore operation.

For example:

dotnet restore

or:

nuget restore

Look closely at the error message.

Do not focus only on:

Restore failed

Find the part describing:

Signature
Certificate
Trusted signer
Fingerprint
Validation

The exact output depends on the NuGet tooling and configuration in use.

Check Which NuGet Configuration Is Being Used

A common troubleshooting mistake is editing the wrong configuration file.

NuGet configuration can come from multiple locations depending on the operating system and environment.

A developer machine may use one configuration while CI uses another.

For example:

Developer machine
       |
       +-- User configuration
       |
       +-- Repository configuration
       |
       +-- Machine configuration

CI runner
       |
       +-- Runner configuration
       |
       +-- Repository configuration

Therefore, changing a local configuration file does not necessarily fix the CI pipeline.

Always determine which configuration is actually being loaded in the failing environment.

Check Your Repository's NuGet Configuration

Look for files such as:

NuGet.config
nuget.config

A repository may contain configuration similar to:

<configuration>
  <config>
    <add key="signatureValidationMode" value="require" />
  </config>

  <trustedSigners>
    ...
  </trustedSigners>
</configuration>

Inspect the trusted signer section carefully.

Look for certificate fingerprints and repository or author trust rules.

Example of a Certificate-Based Policy

A simplified example might look like:

<trustedSigners>
  <author name="ExamplePublisher">
    <certificate
      fingerprint="0123456789ABCDEF..."
      hashAlgorithm="SHA256"
      allowUntrustedRoot="false" />
  </author>
</trustedSigners>

The important values are:

Publisher
Fingerprint
Hash algorithm
Certificate trust settings

If the certificate changes, the fingerprint may need to be updated.

Do not copy a fingerprint from an unverified source.

Verify the New Certificate Before Updating Policy

This is the most important security step.

If your package restore fails because a signing certificate changed, do not simply take the new fingerprint from an error message and add it to the trusted signer list.

First verify that the new certificate belongs to the expected publisher.

A safe verification process should involve:

  1. Confirming the package source.

  2. Confirming the expected publisher.

  3. Inspecting the package signature.

  4. Checking the new certificate details.

  5. Confirming the certificate fingerprint.

  6. Reviewing the certificate chain.

  7. Comparing the information with trusted publisher information.

  8. Updating the policy through normal code review.

The exact verification process depends on your organization's security controls.

Why Blindly Updating the Fingerprint Is Dangerous

Imagine this policy:

Old fingerprint
ABC123

Your build starts failing.

You receive a new fingerprint:

XYZ789

A dangerous response would be:

Replace ABC123 with XYZ789

without checking where XYZ789 came from.

The policy exists to enforce trust.

If you bypass the verification step, you reduce the value of the policy.

A better approach is:

Validation failure
      |
      v
Identify new certificate
      |
      v
Verify publisher identity
      |
      v
Verify certificate
      |
      v
Review fingerprint
      |
      v
Update policy
      |
      v
Test restore

Updating the Trusted Signer Policy

Once the new certificate has been independently verified, update the relevant trusted signer configuration.

For example:

<trustedSigners>
  <author name="ExamplePublisher">
    <certificate
      fingerprint="NEW-FINGERPRINT..."
      hashAlgorithm="SHA256"
      allowUntrustedRoot="false" />
  </author>
</trustedSigners>

If both old and new certificates need to remain valid during a transition, the organization may need a policy that allows both certificates temporarily.

The correct approach depends on the publisher's signing lifecycle and your organization's security requirements.

Supporting Multiple Certificates During Rotation

Certificate rotation can create a transition period.

For example:

Before rotation

Certificate A
     |
     v
Packages

During migration:

Certificate A + Certificate B
          |
          v
Packages

After migration:

Certificate B
     |
     v
Packages

A temporary overlap can prevent existing packages from becoming unusable while new packages are signed with the replacement certificate.

However, retaining old certificates indefinitely can weaken the purpose of certificate-specific trust.

Remove obsolete trust entries according to your organization's certificate lifecycle policy.

Testing the Updated Policy

Do not update the production CI configuration and assume everything is fixed.

Test the change in an isolated environment first.

Run:

dotnet restore

Then verify:

Package restore succeeds
Signature validation succeeds
Expected packages are accepted
Unexpected packages remain rejected

If the repository uses a lock file or package lock strategy, test restoration using the same conditions as CI.

Test Both Positive and Negative Cases

A strong test does not only verify that the expected package works.

You should also verify that the policy still rejects packages that do not meet your trust requirements.

Conceptually:

Test

Expected Result

Package signed by trusted certificate

Accepted

Package signed by new verified certificate

Accepted after policy update

Package with unexpected signer

Rejected

Package with invalid signature

Rejected

Package with modified content

Rejected

The exact testing method depends on your NuGet setup.

CI/CD Considerations

A local restore succeeding does not prove that CI will succeed.

CI environments can differ in:

Make sure the updated trusted signer policy is available to the CI job.

For example, a workflow may execute:

steps:
  - uses: actions/checkout@v4

  - uses: actions/setup-dotnet@v4
    with:
      dotnet-version: '10.x'

  - name: Restore
    run: dotnet restore

  - name: Build
    run: dotnet build --no-restore

  - name: Test
    run: dotnet test --no-build

The restore step is where signature validation problems commonly become visible.

Common Mistakes

Disabling Signature Validation

A restore failure can be frustrating, but disabling signature validation removes the control that detected the trust mismatch.

Investigate the certificate instead.

Trusting Every Certificate From a Package Source

A package repository and a trusted signer are not necessarily the same security boundary.

Use the trust model appropriate for your organization.

Copying a Fingerprint Without Verification

A certificate fingerprint should be independently verified before being added to a trusted policy.

Updating Only the Developer Machine

If CI uses a repository-level NuGet.config, changing a user-level configuration will not solve the pipeline failure.

Keeping Old Certificates Forever

Temporary overlap can be useful during rotation, but obsolete trust entries should eventually be removed.

Updating Multiple Security Policies at Once

Make changes easy to review and audit.

A focused certificate update is easier to investigate if something goes wrong.

Troubleshooting Checklist

If package restore starts failing after a certificate change, check the following:

[ ] Identify the package that failed validation
[ ] Confirm the package source
[ ] Identify the signing certificate
[ ] Compare its fingerprint with the trusted policy
[ ] Verify the publisher identity
[ ] Verify the new certificate
[ ] Check the hash algorithm
[ ] Confirm which NuGet.config is being used
[ ] Reproduce the problem locally
[ ] Test the updated policy
[ ] Test rejection of an unexpected signer
[ ] Run the complete CI pipeline
[ ] Remove obsolete trust entries when appropriate

Advantages of Strict Trusted Signer Policies

  1. Stronger package trust controls - Teams can define which publishers or certificates are accepted.

  2. Better supply-chain visibility - Unexpected signing identities can be detected.

  3. Early failure - Configuration problems can stop an untrusted package from entering a build.

  4. Centralized policy - Teams can enforce consistent package validation.

  5. Improved auditability - Trust decisions can be represented in version-controlled configuration.

Disadvantages and Trade-Offs

  1. Certificate rotation requires maintenance.

  2. Incorrect configuration can break package restore.

  3. CI and developer environments can become inconsistent.

  4. Certificate-specific policies require careful lifecycle management.

  5. Troubleshooting can be more difficult than ordinary package restore failures.

Recommended Approach for Certificate Changes

When a trusted package publisher changes its signing certificate, follow this sequence:

Detect validation failure
        ↓
Identify the package and certificate
        ↓
Verify the new signing identity
        ↓
Confirm the certificate fingerprint
        ↓
Review the trust policy
        ↓
Update NuGet.config
        ↓
Test package restore
        ↓
Test CI
        ↓
Verify rejection of unexpected signers
        ↓
Remove obsolete certificate entries

This approach preserves the purpose of the trust policy while allowing legitimate certificate rotation.

Conclusion

A NuGet signing certificate change can break a trusted signer policy even when the package itself is legitimate and comes from the expected publisher.

The reason is straightforward: a strict policy may trust a specific certificate or signing identity, while the publisher has started using a new certificate.

The right response is not to disable signature validation or blindly replace the old fingerprint. First identify the certificate change, verify the new signing identity, update the appropriate NuGet.config, and test both successful and failed validation scenarios.

For production .NET environments, trusted signer configuration should be treated as security-sensitive infrastructure. Keep it version-controlled, review changes carefully, test CI separately from developer machines, and remove obsolete trust entries after certificate migrations are complete.