Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 3, 2025

Description

Adds DoNotUnpack metadata flag to FileSignInfo and FileExtensionSignInfo that signs containers at the top level without unpacking. Prevents signing checked-in binaries in source archives.

Changes

  • SignToolConstants: Added DoNotUnpack constant
  • SignInfo: Added DoNotUnpack property and WithDoNotUnpack() method
  • FileSignInfoEntry: New class to hold certificate name and DoNotUnpack flag for FileSignInfo entries
  • SignToolTask: Parse DoNotUnpack metadata from both FileSignInfo and FileExtensionSignInfo
  • Configuration.TrackFile: Skip TryBuildZipData/TryBuildWixData when DoNotUnpack is set via SignInfo
  • FileSignInfo: ShouldRepack now uses SignInfo.DoNotUnpack
  • Tests: Added coverage for FileSignInfo, FileExtensionSignInfo, and detached signature scenarios:
    • ContainerSigningWithDoNotUnpackViaFileSignInfo - verifies container is signed without unpacking via FileSignInfo
    • ContainerSigningWithDoNotUnpackViaFileExtensionSignInfo - verifies container is signed without unpacking via FileExtensionSignInfo
    • ContainerSigningWithoutDoNotUnpack - verifies normal unpacking behavior
    • ContainerSigningWithDoNotUnpackAndDetachedSignature - verifies detached signature works with DoNotUnpack

Usage

Via FileSignInfo (per-file):

<FileSignInfo Include="dotnet-sdk-source.tar.gz" CertificateName="LinuxSign" DoNotUnpack="true" />

Via FileExtensionSignInfo (per-extension):

<FileExtensionSignInfo Include=".tar.gz" CertificateName="LinuxSign" DoNotUnpack="true" />

With DoNotUnpack=true, the container is signed as-is without extracting or signing nested binaries. This works with both regular signing and detached signature signing (.sig files).

Precedence

FileSignInfo takes precedence over FileExtensionSignInfo for the DoNotUnpack value. This allows the same file to be signed without unpacking when it appears at the top level, but still be unpacked when nested in another container (unless explicitly overridden by FileSignInfo).

To double check:

Original prompt

This section details on the original issue you should resolve

<issue_title>Allow Signing of Containers Without Unpacking</issue_title>
<issue_description>Currently, when we attempt to sign containers using SignTool, the process unpacks the container and signs artifacts inside them. For some containers, such as the source-built source archives, this leads to the risk of signing artifacts, like binaries, that were checked into the repo. We need to add a feature to SignTool that allows signing of the top-level container without unpacking.</issue_description>

<agent_instructions>SignTool is in https://github.com/dotnet/arcade/tree/main/src/Microsoft.DotNet.SignTool. As part of this work, also add some unit tests in https://github.com/dotnet/arcade/blob/main/src/Microsoft.DotNet.SignTool.Tests/SignToolTests.cs for this feature.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add feature to sign top-level containers without unpacking Add DoNotUnpack flag to sign containers without extracting contents Dec 3, 2025
Copilot AI requested a review from ellahathaway December 3, 2025 18:12
}

[Fact]
public void ContainerSigningWithDoNotUnpack()
Copy link
Member

Choose a reason for hiding this comment

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

@copilot - please also add a test for not unpacking a file that is signed with a detached signature

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added test ContainerSigningWithDoNotUnpackAndDetachedSignature that verifies a container with DoNotUnpack=true and a certificate supporting detached signatures is signed at the top level without unpacking its contents. Commit: 19c6497

@mmitche
Copy link
Member

mmitche commented Dec 4, 2025

@copilot Because a top-level file could be duplicated within other archives (e.g. an MSI at the top level as well as within a VS.* nupkg), I think a better way to implement this is via a new bit of metadata on FileSignInfo and other certificate specification metadata.

Copy link
Contributor Author

Copilot AI commented Dec 4, 2025

@copilot Because a top-level file could be duplicated within other archives (e.g. an MSI at the top level as well as within a VS.* nupkg), I think a better way to implement this is via a new bit of me...

I understand the concern about duplicated files. To clarify the intended design: should the DoNotUnpack behavior be specified via FileSignInfo (per-file name) or FileExtensionSignInfo (per-extension like .tar.gz)? For example, would the configuration look like:

<FileSignInfo Include="dotnet-sdk-source.tar.gz" CertificateName="LinuxSign" DoNotUnpack="true" />

Or via extension:

<FileExtensionSignInfo Include=".tar.gz" CertificateName="LinuxSign" DoNotUnpack="true" />

This would allow the same file to be signed without unpacking when it appears at the top level, but still be unpacked when nested in another container. Please confirm and I'll refactor the implementation accordingly.

Copilot AI requested a review from mmitche December 4, 2025 17:14
@ellahathaway
Copy link
Member

I understand the concern about duplicated files. To clarify the intended design: should the DoNotUnpack behavior be specified via FileSignInfo (per-file name) or FileExtensionSignInfo (per-extension like .tar.gz)? For example, would the configuration look like:

<FileSignInfo Include="dotnet-sdk-source.tar.gz" CertificateName="LinuxSign" DoNotUnpack="true" />

Or via extension:

<FileExtensionSignInfo Include=".tar.gz" CertificateName="LinuxSign" DoNotUnpack="true" />

This would allow the same file to be signed without unpacking when it appears at the top level, but still be unpacked when nested in another container. Please confirm and I'll refactor the implementation accordingly.

@copilot - please implement this for both file name (FileSignInfo) and file extension (FileExtensionSignInfo).

Copy link
Contributor Author

Copilot AI commented Dec 4, 2025

I understand the concern about duplicated files. To clarify the intended design: should the DoNotUnpack behavior be specified via FileSignInfo (per-file name) or FileExtensionSignInfo (per-ext...

Implemented DoNotUnpack for both FileSignInfo (per-file name) and FileExtensionSignInfo (per-extension). The implementation adds a new FileSignInfoEntry class to hold both certificate name and DoNotUnpack flag, and extends SignInfo to carry the DoNotUnpack state from extension-based configuration.

Usage examples:

<!-- Per-file via FileSignInfo -->
<FileSignInfo Include="dotnet-sdk-source.tar.gz" CertificateName="LinuxSign" DoNotUnpack="true" />

<!-- Per-extension via FileExtensionSignInfo -->
<FileExtensionSignInfo Include=".tar.gz" CertificateName="LinuxSign" DoNotUnpack="true" />

Added tests for both approaches. Commit: e7a45b0

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:

  • securitytools.pkgs.visualstudio.com
    • Triggering command: /opt/hostedtoolcache/CodeQL/2.23.6/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp /opt/hostedtoolcache/CodeQL/2.23.6/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp (dns block)

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

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.

Allow Signing of Containers Without Unpacking

3 participants