Skip to content

feat(package): sing windows binaries [NR-489681]#1938

Merged
sigilioso merged 3 commits intomainfrom
feat/sing-windows-exec
Dec 17, 2025
Merged

feat(package): sing windows binaries [NR-489681]#1938
sigilioso merged 3 commits intomainfrom
feat/sing-windows-exec

Conversation

@sigilioso
Copy link
Contributor

@sigilioso sigilioso commented Dec 11, 2025

Implementation details

Implements Windows binary signing for newrelic-agent-control and newrelic-agent-control-cli executables using PFX code signing certificates during the GoReleaser build process.

The implementation uses a containerized Docker-based signing workflow that integrates with GoReleaser's post-build hooks. When Windows binaries are compiled, a signing script is executed. It uses osslsigncode for signing.

Pipelines

The GitHub Actions workflow exposes signing credentials as environment variables to GoReleaser. When the skip_sign input parameter is set to true, both packages signing and Windows executable signing are disabled (SKIP_WINDOWS_SIGN environment variable disables Windows executable signing).

Manual testing

To test the signing implementation locally with self-signed certificates:

  1. Generate Test Credentials:

    ./build/scripts/windows-exec-sign/generate-testing-credentials.s
  2. Sent environment variables:

    export PFX_CERT_BASE64=$(cat local/testing-pfx-cert/certificate_pfx_base64)
    export PFX_PASSPHRASE="TestPassword123"
  3. Run goreleaser or sing directly

    # Test signing a single executable
    export EXECUTABLE=/path/to/your/binary.exe
    ./build/scripts/windows-exec-sign/sign.s
     # goreleaser (--skip=sing) skips package signature only, windows binaries are signed
     goreleaser release --skip=publish --skip=sign --clean --verbose --snapshot --verbose 
  4. Check signature (on Windows):
    The self-signed certificate will not be trusted by Windows but we still can check that the binary contains the signature.

    File properties example image

Checklist

  • Provided a meaningful title following conventional commit style.
  • Included a detailed description for the Pull Request.
  • Documentation under docs is aligned with the change.
  • Follows guidelines for Pull Requests in CONTRIBUTING.md.
  • Follows log level guidelines.

@sigilioso sigilioso requested a review from a team as a code owner December 11, 2025 09:33
@sigilioso sigilioso force-pushed the feat/sing-windows-exec branch from 048c73f to e84c8fb Compare December 11, 2025 11:23
Copy link
Contributor

@DavSanchez DavSanchez left a comment

Choose a reason for hiding this comment

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

Looking good! A few doubts

@sigilioso sigilioso requested review from a team and DavSanchez December 11, 2025 13:49
@sigilioso sigilioso force-pushed the feat/sing-windows-exec branch from e84c8fb to 4b3d13a Compare December 12, 2025 08:30
gsanchezgavier
gsanchezgavier previously approved these changes Dec 12, 2025
Copy link
Contributor

@gsanchezgavier gsanchezgavier left a comment

Choose a reason for hiding this comment

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

LGTM, wonder if makes sense to have some sort of test (outside this task) that validates that we are releasing signed binaries , i think we are covering with linux due to the gpg check when installing from package managers

Comment on lines 97 to 98
PFX_CERTIFICATE_BASE64: ${{ secrets.OHAI_PFX_CERTIFICATE_BASE64 }} # base64 encoded
PFX_PASSPHRASE: ${{ secrets.OHAI_PFX_PASSPHRASE }}
Copy link
Contributor

@gsanchezgavier gsanchezgavier Dec 12, 2025

Choose a reason for hiding this comment

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

would make sense to pass this as secrets , using them only in the pre-release wf to make more difficult to sign testing assets? i think same for the GPG

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It makes total sense!

Copy link
Contributor

Choose a reason for hiding this comment

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

i pasted somehting complealty unrelated in the link 😆 , just updated it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I got the point anyway, thanks!

Copy link
Contributor Author

@sigilioso sigilioso Dec 15, 2025

Choose a reason for hiding this comment

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

I've changed it here: 475b1e1 LMKWYT

@sigilioso
Copy link
Contributor Author

wonder if makes sense to have some sort of test (outside this task) that validates that we are releasing signed binaries , i think we are covering with linux due to the gpg check when installing from package managers

🤔 I also think we should check it. I can trigger a nightly before merging and, at very least, check manually that the binaries are signed as expected. Once that is verified, we can figure out a way check the signature on Windows machines (when packages are signed and uploaded)

@sigilioso
Copy link
Contributor Author

sigilioso commented Dec 12, 2025

I've just triggered a nightly and checked the signature of the corresponding binaries. It works as expected 🎉

Signature check
> Get-AuthenticodeSignature .\newrelic-agent-control.exe


    Directory: C:\Users\calvarez\Downloads\newrelic-agent-control-windows_x86_64-pc-windows-msvc


SignerCertificate                         Status                                                       Path
-----------------                         ------                                                       ----
99C80227B0FD6238225C5E27227115F511EC0C1A  Valid                                                        newrelic-agent-control.exe


> Get-AuthenticodeSignature .\newrelic-agent-control.exe | Format-List *


SignerCertificate      : [Subject]
                           CN="New Relic, Inc.", O="New Relic, Inc.", L=San Francisco, S=California, C=US

                         [Issuer]
                           CN=DigiCert Trusted G4 Code Signing RSA4096 SHA384 2021 CA1, O="DigiCert, Inc.", C=US

                         [Serial Number]
                           01C331132C221038E2DEBD4E825F51CD

                         [Not Before]
                           7/11/2024 2:00:00 AM

                         [Not After]
                           9/10/2027 1:59:59 AM

                         [Thumbprint]
                           99C80227B0FD6238225C5E27227115F511EC0C1A

TimeStamperCertificate : [Subject]
                           CN=DigiCert SHA256 RSA4096 Timestamp Responder 2025 1, O="DigiCert, Inc.", C=US

                         [Issuer]
                           CN=DigiCert Trusted G4 TimeStamping RSA4096 SHA256 2025 CA1, O="DigiCert, Inc.", C=US

                         [Serial Number]
                           0A80EF184B8DF10582D1C476A7957468

                         [Not Before]
                           6/4/2025 2:00:00 AM

                         [Not After]
                           9/4/2036 1:59:59 AM

                         [Thumbprint]
                           DD6230AC860A2D306BDA38B16879523007FB417E

Status                 : Valid
StatusMessage          : Signature verified.
Path                   : C:\Users\calvarez\Downloads\newrelic-agent-control-windows_x86_64-pc-windows-msvc\newrelic-agent-control.exe
SignatureType          : Authenticode
IsOSBinary             : False

I'm trying to add a validation step to check the binaries are signed right after packaging

@sigilioso sigilioso force-pushed the feat/sing-windows-exec branch from 3c62815 to d147e26 Compare December 15, 2025 08:27
@sigilioso
Copy link
Contributor Author

sigilioso commented Dec 15, 2025

The validation for Windows binaries signatures was added in the latest commit. After triggering a nightly, the check is working as expected: workflow execution

@sigilioso sigilioso force-pushed the feat/sing-windows-exec branch from f339411 to 475b1e1 Compare December 15, 2025 11:02
@sigilioso sigilioso requested review from a team and gsanchezgavier December 15, 2025 11:14
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GPG_PASSPHRASE: ${{ secrets.OHAI_GPG_PASSPHRASE }}
GPG_PRIVATE_KEY_BASE64: ${{ secrets.OHAI_GPG_PRIVATE_KEY_BASE64 }} # base64 encoded
GITHUB_TOKEN: ${{ secrets.gh_token }}
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we using that instead of ${{ secrets.GITHUB_TOKEN }}?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We are using it to accomplish this. I decided to name them differently (using the lowercase and gh_token instead of github_token to avoid colliding with a Github reserved word) to be very explicit when using the workflow (and prevent us from using secrets: inherit again).

Copy link
Contributor

Choose a reason for hiding this comment

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

Question: This is not used anywhere right? What's the purpose of adding it? Future tests or manual tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its purpose is having a quick way of testing the signature part locally, in case we are changing the goreleaser script or anything that could affect the windows binaries. Is it clear enough or does it needs more docs/comments?

@sigilioso sigilioso requested review from a team and danielorihuela December 16, 2025 13:09
Copy link
Contributor

@gsanchezgavier gsanchezgavier left a comment

Choose a reason for hiding this comment

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

Thanks!

@sigilioso sigilioso merged commit 54920bd into main Dec 17, 2025
56 checks passed
@sigilioso sigilioso deleted the feat/sing-windows-exec branch December 17, 2025 09:14
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.

4 participants

Comments