Skip to content

$PSBPreference.Sign.SkipCertificateValidation has no effect on the Store and Thumbprint sources it is documented for #193

Description

@tablackburn

Found while documenting the Sign settings for #189.

PowerShellBuild/build.properties.ps1 documents the setting as applying to Store and Thumbprint:

When true and using the Store or Thumbprint sources, skip the certificate validity check that ensures the certificate is not expired and has a private key. This is not recommended for production use but can be useful in CI environments where certificates are frequently renewed and updated.

Get-PSBuildCertificate implements the opposite. The switch is only consulted for EnvVar and PfxFile:

# Get-PSBuildCertificate.ps1:180
if ($cert -and -not $SkipValidation -and ($resolvedSource -eq "EnvVar" -or $resolvedSource -eq "PfxFile")) {

For Store and Thumbprint the same two checks run unconditionally, inside the selection filter, where the switch cannot reach them:

# Store, line 133
Get-ChildItem -Path $CertStoreLocation -CodeSigningCert |
    Where-Object { $_.HasPrivateKey -and $_.NotAfter -gt (Get-Date) } |
    Select-Object -First 1

# Thumbprint, lines 147-152
Where-Object {
    ($_.Thumbprint -replace "\s", "") -ieq $normalizedThumbprint -and
    $_.HasPrivateKey -and
    $_.NotAfter -gt (Get-Date)
}

Why it matters

The setting exists for the CI case the comment names — a certificate that has just expired or is being rotated. A consumer who sets $PSBPreference.Sign.SkipCertificateValidation = $true with a store certificate does not get a bypass. The certificate is filtered out before validation is ever considered, and the build fails with NoCertificateFound, which points at a missing certificate rather than at the expiry that actually caused it. The documented escape hatch does not work for the source it is documented for.

Note the asymmetry in how the two paths report failure, too: EnvVar and PfxFile throw the specific CertificateExpired / CertificateMissingPrivateKey messages, while Store and Thumbprint silently drop the certificate and fall through to the generic one.

Which is wrong, the comment or the code?

That is the decision this issue needs, and it is a behavior call rather than a documentation one:

  • Fix the code — move the HasPrivateKey / NotAfter checks out of the Where-Object filters for Store and Thumbprint and into the shared validation block, so SkipValidation governs all four sources uniformly. This makes the setting do what it says, and as a side effect the two paths would start reporting why a certificate was rejected. It is a behavior change: a build that currently skips an expired store certificate and picks a valid one further down the list would instead select the expired one when validation is skipped.
  • Fix the comment — narrow it to EnvVar and PfxFile, and say plainly that Store and Thumbprint always filter on validity with no way to opt out.

I lean toward fixing the code, because the CI scenario the comment describes is real and currently unserved, but it is a 1.0.0 behavior change and should be a maintainer decision.

Scope note

build.properties.ps1 was deliberately left unchanged in #190. That PR documents the implemented behavior in the README rather than the commented behavior, so the README is accurate today whichever way this issue is resolved.

Related: #178, another setting that read one name and bound nothing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions