Artifact configuration

Abstract

The artifact configuration describes the structure of the artifacts you want to sign. For simple artifacts, you can use predefined configurations to get started quickly. For signing several artifacts together, and for more complex artifacts, specify the structure of your artifact and provide signing directives using XML.

InformationTips:

  • Basic artifact configurations can be generated from sample artifacts. However, this is feature is not yet integrated in the online application. Until then, feel free to ask our support for help at support@singpath.io. Please attach your sample artifact.
  • Alternatively, if you don't know the internal structure of your artifact, extract container files to your disk first.
  • Use a schema-aware XML editor, such as Microsoft Visual Studio, to edit your artifact configuration. (Some tools may require you to download the schema).

Deep signing

In case you have more complex, nested artifacts, you might want to not only sign the container itself (for instance, an MSI installer package), but also all files that are shipped within the container (e.g. .exe and .dll files within the MSI installer). Therefore, every container format can contain multiple other file or directory elements to be signed. Each of those will be extracted, signed, and then put back into the container file during the signing process. In order for SignPath to find the right file, all inner elements need a path attribute.

File elements

Every XML description is wrapped in an <artifact-configuration> root element which contains exactly one file element. This file element specifies the type of artifact and signing method. Optionally, you can restrict the name of the file using the path attribute.

Container-format elements may contain other file elements for deep signing.

File element types and signing directives

Element Container format Signing directive Extensions Description
<pe-file> No <authenticode-sign> .acm, .ax, .cpl, .dll, .drv, .efi, .exe, .fon, .mui, .ocx, .scr, .sys, .tsp Portable Executable (PE) files: EXE, DLL, and other executable files
<powershell-file> No <authenticode-sign> .ps1, .psm1, psd1, .psdc1, .ps1xml PowerShell scripts and modules
<zip-file> Yes (none) .zip ZIP archives
<msi-file> Yes <authenticode-sign> .msi, .msm, .msp Microsoft installer files
<cab-file> Yes <authenticode-sign> .cab Windows cabinet files
<appx-file> Yes <authenticode-sign> .appx, .appxbundle App packages for Microsoft Store/Universal Windows Platform

Deep signing is not yet supported.

<opc-file> Yes <opc-sign> .vsix, .xps, ... Open Packaging Conventions (OPC) files including Visual Studio Extensions (VSIX)
<nupkg-file> Yes <nuget-sign> .nupkg NuGet packages
<directory> Yes <clickonce-sign> Directories within container files

File element examples

Signing an MSI package

<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
  <msi-file>
    <authenticode-sign/>
  </msi-file>
</artifact-configuration>

See Examples for more complex artifact configurations.

Signing multiple artifacts

If you want to sign multiple independent artifacts in one step, you need to package them into a ZIP archive before processing.

You can combine signing multiple artifacts with deep signing.

<directory> element

All supported container formats have an internal directory structure. You can see this structure if you extract a container to a local disk.

You can either specify these directories in the path attribute of each file element, or nest these file elements within <directory> elements.

<directory> elements are also used for ClickOnce signing.

<directory> example

The following fragment is equivalent to
<zip-file>
  <pe-file path="bin/program.exe">
    <authenticode-sign/>
  </pe-file>
</zip-file>
<zip-file>
  <directory path="bin">
    <pe-file path="program.exe">
      <authenticode-sign/>
    </pe-file>
  </directory>
</zip-file>

Signing methods

Specify signing directives in file and directory elements. See file elements for available methods per element type.

For file and directory sets, specify the signing directive in the <for-each> element.

<authenticode-sign>

Microsoft Authenticode is the primary signing method on the Windows platform. Authenticode is a versatile and extensible mechanism that works for many different file types:

  • Portable Executable (PE) files: EXE, DLL, and some other executable file formats including device drivers
  • Installation formats: AppX, MSI, and CAB
  • PowerShell scripts and modules

Using <authenticode-sign> is equivalent to using Microsoft's SignTool.exe.

<clickonce-sign>

ClickOnce signing, also called 'manifest signing', is a method used for ClickOnce applications and Microsoft Office Add-ins.

ClickOnce signing applies to directories, not to individual files. Therefore, you need to specify a <directory> element for this method. If you want to sign files in the root directory of a container, specify path=".".

<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
  <zip-file>
    <directory path=".">
      <clickonce-sign/>
    </directory>
  </zip-file>
</artifact-configuration>

Using <clickonce-sign> is equivalent to using Microsoft's mage.exe.

<nuget-sign>

NuGet package signing is currently being introduced to the NuGet Gallery.

Although the NuGet Package format is based on OPC (see next section), it uses its own specific signing format.

Using <nuget-sign> is equivalent to using Microsoft's nuget sign command.

<opc-sign>

The Open Packaging Conventions (OPC) specification has its own signature format. Since OPC is the foundation for several file formats, it is not strictly a code signing format. However, code signing is used for Visual Studio Extensions (VSIX).

Other OPC formats include:

  • Open XML Paper Specification (OpenXPS)
  • Office Open XML files (Microsoft Office)

Note that while OPC signing can be applied to all OPC formats, specific applications and formats do not necessarily use or verify signatures, or even require a different signing format (case in point: NuGet packages).

Using <opc-sign> for Visual Studio Extensions is equivalent to using Microsoft's VSIXSignTool.exe.

Using wildcards

Every path attribute can contain the following wildcard patterns:

Wildcard Description
* Matches any number of any character (including none, excluding the directory separator)
? Matches any single character
[abc] Matches one character given in the bracket
[a-z] Matches one character from the range given in the bracket
[!abc] Matches one character that is not given in the bracket
[!a-z] Matches one character that is not from the range given in the bracket
** Matches any number of path/directory segments. When used, they must be the only contents of the dedicated segment.

If wildcards are used, optional max-matches and min-matches parameters can be specified to limit the number of files which are allowed to match the wildcard expression. Both default to 1. (You can also use min-matches="0" for optional elements even without wildcards.)

File and directory sets

If multiple files or directories should be handled in the same way, you can enumerate them using one of the following file or directory set elements:

  • <directory-set>
  • <pe-file-set>
  • <zip-file-set>
  • <msi-file-set>
  • <cab-file-set>
  • <opc-file-set>
  • <nupkg-file-set>

Each set element contains:

  • an <include> element for each file (or pattern) to be processed
  • a <for-each> element that will be applied to all included elements of the set

A set's <for-each> element can include the same child elements as the corresponding simple file or directory element:

  • <pe-file> supports <authenticode-signing/>
  • therefore <pe-file-set> supports <authenticode-signing/> within the <for-each> element

Sets are especially useful if your artifacts contain repeating nested structures.

File set example

The following fragment is equivalent to
<pe-file path="first.dll">
  <authenticode-sign/>
</pe-file>

<pe-file path="second.dll">
  <authenticode-sign/>
</pe-file>
<pe-file-set>
  <include path="first.dll">
  <include path="second.dll">
  <for-each>
    <authenticode-sign/>
  </for-each>
</pe-file>

File attribute restrictions

For Microsoft Portable Executable (PE) files, the existence of their Product Name / Product Version header attributes can be enforced by setting the productName and productVersion attributes on the <pe-file>, <pe-file-set> and including <include> elements. The value of the <include> overrides any value set on the <pe-file-set> element.

File attribute restriction example

<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
  <msi-file>
    <!-- requires all pe-files to have the respective attributes set -->
    <pe-file-set productName="YourProductName" productVersion="1.0.0.0"> 
      <include path="main.exe" />
      <!-- overrides the value of the parent pe-file-set -->
      <include path="resources*.resource.dll" max-occurs="unbounded" productVersion="1.0.1.0" />
      <for-each>
        <authenticode-sign />
      </for-each>
    </pe-file-set>
    <authenticode-sign /> <!-- finally sign the MSI file -->
  </msi-file>
</artifact-configuration>

Examples

Information Examples are shortened

For the sake of clarity, all examples omit the XML prolog. A complete artifact configuration looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
  <!-- ... -->
</artifact-configuration>

Predefined configuration for single Portable Executable file

This configuration works for all PE files.

<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
  <pe-file>
    <authenticode-sign/>
  </pe-file>
</artifact-configuration>

Signing multiple artifacts in a ZIP container

You can sign multiple unrelated artifacts by packing them into a single ZIP file.

<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
  <zip-file>
    <pe-file path="app.exe">
      <authenticode-sign/>
    </pe-file>
    <powershell-file path="setup.ps1">
      <authenticode-sign/>
    </powershell-file>
  </zip-file>
</artifact-configuration>

Deep-signing an MSI installer

This will sign the PE files libs/common.dll and main.exe, then re-package their MSI container and sign it too. It also restricts the name of the MSI container file.

<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
  <msi-file path="MyProduct.v*.msi">
    <directory path="libs">
      <pe-file path="common.dll">
        <authenticode-sign/>
      </pe-file>
    </directory>
    <pe-file path="main.exe">
      <authenticode-sign/>
    </pe-file>
    <authenticode-sign/>
  </msi-file>
</artifact-configuration>

Signing similar directories within an MSI file

This artifact configuration describes an MSI installer package containing several components. These components have a similar structure and are therefore defined as a <directory-set>. Each component contains a main.exe and zero or more resource DLLs.

<artifact-configuration xmlns="http://signpath.io/artifact-configuration/v1">
  <msi-file>
    <directory-set>
      <include path="component1" />
      <include path="component2" />
      <include path="component3" />
      <for-each>
        <pe-file-set>
          <include path="main.exe" />
          <include path="resources*.resource.dll" min-matches="0" max-matches="unbounded" />
          <for-each>
            <authenticode-sign/>
          </for-each>
        </pe-file-set>
      </for-each>
    </directory-set>
    <authenticode-sign/>
  </msi-file>
</artifact-configuration>

Example of a directory structure that would match this configuration:

MyApp.msi
  component1/
    main.exe
    resources/
      de.resource.dll
      en.resource.dll
      fr.resource.dll
  component2/
    main.exe
  component3/
    main.exe
    resources/
      en.resource.dll

Extracting artifact packages

You can use the following tools in order to manually extract files from your artifacts. From the extracted file structure, you can then easily create a matching artifact configuration.

We recommend that you apply these tools to all contained files recursively and create a very specific artifact configuration.

File type Recommended tools
.zip, .cab Extract using tools like WinZip or 7-Zip or Windows Explorer.
.vsix, .nupkg These are just special ZIP archives. Either change the extension to .ZIP or use a tool like 7-Zip to directly extract their contents.
.msi Use the Windows tool msiexec.exe to perform an administrative install. Note that this might execute parts of the MSI file, so only use this for trusted files.
msiexec /a filename.msi TARGETDIR=c:full-path