Skip to main content

CI/CD and Build Tools

The sslTrus remote code signing service can be integrated into CI/CD, application build, and installation package creation workflows, automatically signing release artifacts after compilation or packaging is complete.

Currently supported typical integration scenarios include:

  • GitHub Actions
  • Electron Builder
  • Advanced Installer

Depending on the capabilities of your build tools, you can directly use the sslTrus GitHub Action, call the SignTool CLI, or integrate through the custom signing interfaces provided by your build tools.

GitHub Actions

sslTrus provides an official GitHub Action:

ssltrus-official/code-sign-action

You can directly perform remote code signing on build artifacts in a GitHub Actions Workflow.

The Action will call the sslTrus remote code signing service to complete the signing and directly update the specified files. It is suitable for Linux, macOS, and Windows runners.

Prepare GitHub Secrets

It is recommended to store remote code signing credentials in GitHub Actions Secrets:

SSLTRUS_ACCESS_KEY
SSLTRUS_ACCESS_SECRET
SSLTRUS_CERT_CODE

Do not write the Access Secret directly into the Workflow file.

Basic configuration

- name: Sign files
uses: ssltrus-official/code-sign-action@v1
with:
access-key: ${{ secrets.SSLTRUS_ACCESS_KEY }}
access-secret: ${{ secrets.SSLTRUS_ACCESS_SECRET }}
cert-code: ${{ secrets.SSLTRUS_CERT_CODE }}
files: build/app.exe

After a successful signing, build/app.exe will be directly replaced by the signed file.

Sign multiple files

files supports configuring multiple files using multiple lines:

- name: Sign files
uses: ssltrus-official/code-sign-action@v1
with:
access-key: ${{ secrets.SSLTRUS_ACCESS_KEY }}
access-secret: ${{ secrets.SSLTRUS_ACCESS_SECRET }}
cert-code: ${{ secrets.SSLTRUS_CERT_CODE }}
files: |
build/app.exe
build/library.dll
build/installer.msi

Comma-separated file paths can also be used.

Duplicate file paths are processed only once.

Complete Configuration

- name: Sign files
uses: ssltrus-official/code-sign-action@v1
with:
access-key: ${{ secrets.SSLTRUS_ACCESS_KEY }}
access-secret: ${{ secrets.SSLTRUS_ACCESS_SECRET }}
cert-code: ${{ secrets.SSLTRUS_CERT_CODE }}
files: |
build/app.exe
build/library.dll
build/installer.msi
dry-run: false
timestamp-rfc3161: http://timestamp.acs.microsoft.com
description: Example Application
description-url: https://example.com

Main parameters:

ParameterRequiredDefault valueDescription
access-keyYes-sslTrus Access Key
access-secretYes-sslTrus Access Secret
cert-codeYes-Code signing certificate ID
filesYes-File path to be signed
nicsrsNofalseWhether to use the NICSRS service
dry-runNofalseUse a local test certificate to perform test signing
timestamp-rfc3161NoautoRFC 3161 timestamp server
descriptionNo-Program description written into the Authenticode signature
description-urlNo-Program URL written into the Authenticode signature

Complete Workflow Example

The following is an example of compiling, signing, and uploading build artifacts in a Windows Runner:

name: Build and Sign

on:
workflow_dispatch:

permissions:
contents: read

jobs:
build:
runs-on: windows-latest

steps:
- name: Check out repository
uses: actions/checkout@v7

- name: Build
run: |
# 在这里执行实际构建命令

- name: Sign files
uses: ssltrus-official/code-sign-action@v1
with:
access-key: ${{ secrets.SSLTRUS_ACCESS_KEY }}
access-secret: ${{ secrets.SSLTRUS_ACCESS_SECRET }}
cert-code: ${{ secrets.SSLTRUS_CERT_CODE }}
files: |
build/app.exe
build/library.dll
timestamp-rfc3161: http://timestamp.acs.microsoft.com

- name: Upload signed files
uses: actions/upload-artifact@v7
with:
name: signed-files
path: |
build/app.exe
build/library.dll

Recommended to place the signing step in:

Compile → Package → Code signing → Release

Before the publish step in the workflow.

Multi-platform Runner

GitHub Actions can be invoked in different Runners:

strategy:
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest

runs-on: ${{ matrix.os }}

Therefore, even if the build task runs on Linux or macOS, you can use the same Action to complete remote signing of supported files.

Dry Run

If you need to verify the Workflow and file processing logic, you can enable:

dry-run: true

This mode uses a local test certificate and does not call the remote code signing service.

For example:

- name: Test signing
uses: ssltrus-official/code-sign-action@v1
with:
access-key: dummy
access-secret: dummy
cert-code: dummy
files: build/app.exe
dry-run: true

dry-run still modifies the target file, so do not interpret it as a preview mode that does not modify files at all.

Electron Builder

Electron Builder can invoke the sslTrus SignTool CLI through a custom signing function, thereby automatically signing Windows executable files and installation packages during the Electron application build process.

Typical workflow:

Electron Builder

customSign

SignTool CLI

sslTrus 远程代码签名服务

云端 HSM

Prerequisites

Before you start, you need:

  • An available sslTrus remote code signing service.
  • Access Key and Access Secret obtained.
  • Code signing certificate number obtained.
  • Electron project built with electron-builder.
  • Build environment capable of executing sslTrus SignTool CLI, downloadable from the sslTrus client release page.

Configure Credentials

Credentials can be passed to the build script through environment variables:

Linux and macOS:

export SIGNTOOL_ACCESS_KEY="YOUR_ACCESS_KEY"
export SIGNTOOL_ACCESS_SECRET="YOUR_ACCESS_SECRET"
export SIGNTOOL_CERT_CODE="YOUR_CERT_CODE"

Windows PowerShell:

$env:SIGNTOOL_ACCESS_KEY = "YOUR_ACCESS_KEY"
$env:SIGNTOOL_ACCESS_SECRET = "YOUR_ACCESS_SECRET"
$env:SIGNTOOL_CERT_CODE = "YOUR_CERT_CODE"

These variables are read by the Electron custom signing script and then passed to the SignTool CLI.

Configuring Electron Builder

In:

electron-builder.mjs

Or in the Electron Builder configuration file actually used by the project, set a custom signing function for Windows:

export default {
win: {
target: [
{
target: 'nsis',
arch: ['x64'],
},
],
sign: customSign,
signingHashAlgorithms: ['sha256'],
},
};

Where win.sign is the custom signing entry point officially provided by Electron Builder. For detailed instructions, see the Electron Builder Windows code signing documentation.

customSign

Responsible for invoking the sslTrus SignTool CLI.

Custom Signing Function

Example:

import { execFileSync } from 'node:child_process';

async function customSign(configuration) {
const {
SIGNTOOL_ACCESS_KEY,
SIGNTOOL_ACCESS_SECRET,
SIGNTOOL_CERT_CODE,
} = process.env;

if (
!SIGNTOOL_ACCESS_KEY ||
!SIGNTOOL_ACCESS_SECRET ||
!SIGNTOOL_CERT_CODE
) {
throw new Error('Missing sslTrus signing credentials');
}

execFileSync(
'./signtool',
[
'sign',
'--access-key',
SIGNTOOL_ACCESS_KEY,
'--access-secret',
SIGNTOOL_ACCESS_SECRET,
'--cert-code',
SIGNTOOL_CERT_CODE,
'--file',
configuration.path,
'--override=true',
'--sha1=false',
'--sha2=true',
'--timestamp-rfc3161=http://timestamp.acs.microsoft.com',
],
{
stdio: 'inherit',
},
);
}

It is recommended to invoke child processes using an array of arguments rather than concatenating a complete shell command, to reduce issues with path escaping and special character handling.

Electron Builder calls the signing function once for each hash algorithm in signingHashAlgorithms. The example above enables only SHA-256, so it calls once per file.

Run the build

After configuration is complete, run Electron Builder as usual:

npx electron-builder build \
--config electron-builder.mjs \
--win \
--x64

Electron Builder automatically calls customSign when it needs to sign files.

A single Electron build may sign multiple files, for example:

MyApp.exe
helper.dll
update.exe
uninstall.exe
MyApp Setup.exe

Therefore, it should not simply be understood as "one Electron build produces only one signature."

The actual number of signatures depends on how many files execute remote signing during the build process.

Advanced Installer

Advanced Installer is an installation package creation tool based on Windows Installer technology.

You can invoke the sslTrus SignTool CLI through Advanced Installer's custom signing tool feature, enabling build artifacts such as MSI, EXE, and CAB to automatically complete remote code signing during the packaging process.

Prerequisites

You need to prepare:

  • sslTrus SignTool CLI, which can be downloaded from the sslTrus client release page.
  • Access Key.
  • Access Secret.
  • Certificate ID.
  • A configured Advanced Installer project.

Configure the custom signing tool

Open the Advanced Installer project's:

Digital Signature

Configuration page.

After enabling code signing, select the signing tool as:

Custom

Set the signing tool path to the sslTrus SignTool CLI executable.

For example:

C:\Tools\sslTrus\signtool.exe

Custom parameters need to be called:

sign

subcommand, and pass the following to the client:

  • Access Key
  • Access Secret
  • Cert Code
  • SHA-2 signature settings
  • Timestamp server
  • File path

It is recommended to provide the Access Key and Access Secret through secure means, and avoid saving the long-term Access Secret in plaintext in publicly accessible project files.

SignTool parameter example

The corresponding signing logic looks like:

signtool.exe sign ^
--access-key="YOUR_ACCESS_KEY" ^
--access-secret="YOUR_ACCESS_SECRET" ^
--cert-code="YOUR_CERT_CODE" ^
--nest=true ^
--sha1=false ^
--sha2=true ^
--timestamp-rfc3161=http://timestamp.acs.microsoft.com ^
--desc="Example Application" ^
--override=true ^
--file "app.exe"

In Advanced Installer, the actual file path should be passed in by its custom signing tool mechanism, not hardcoded as the app.exe in the example.

Build Configuration

If using Advanced Installer to automatically sign files within the installer package, you need to check both the build and compression methods.

Depending on the actual project configuration, certain CAB archiving methods may affect the custom signing process. Confirm that the files requiring final signatures can be invoked at the corresponding stage.

After configuration is complete, you can check on the Digital Signature page in Advanced Installer:

Files configured for signing

This confirms which files will be signed during the build process.

Number of Signatures

Advanced Installer may sign multiple files separately during a single installer package build process.

For example:

FileSignature
app.exe1 time
helper.dll1 time
uninstall.exe1 time
installer.msi1 time
Total4 times

Therefore:

一次构建 ≠ 一次签名

It should be calculated based on the actual number of files that complete remote signing or the number of signing actions performed.

Signing count

CI/CD and build tools usually automatically process multiple artifacts, so the signing count requires special attention.

Basic principle:

签名次数 = 实际成功完成的签名动作数量

For example:

app.exe        → 1 次
library.dll → 1 次
installer.msi → 1 次

If all three files are signed successfully:

合计 = 3 次

Build tools such as Electron Builder and Advanced Installer may also automatically generate and sign:

  • The main executable.
  • DLLs.
  • The updater.
  • The uninstaller.
  • MSI.
  • EXE installation packages.
  • Other auxiliary executable files.

Therefore, the number of signatures should be confirmed based on build logs and actual signed artifacts, rather than estimated according to the number of Pipeline or Build executions.

For more rules, see Reference.

Timestamp

For officially released software, it is generally recommended to add a trusted timestamp.

GitHub Actions, Electron Builder, and Advanced Installer integrations can all use RFC 3161 timestamps, for example:

http://timestamp.acs.microsoft.com

Timestamps do not constitute a new code signing operation and do not separately increase the code signing count.

For protocol support and usage limitations of different TSAs, refer to Reference Materials.

Credential Security

The following should be specially protected in automation environments:

Access Key
Access Secret
Cert Code

The Access Secret should be managed as a Secret and must not be:

  • Committed to a Git repository.
  • Written in plaintext into public workflows.
  • Output to build logs.
  • Written into public Docker images.
  • Passed to third-party build systems through insecure methods.

GitHub Actions recommends using:

GitHub Actions Secrets

Other CI/CD systems should use their corresponding Secret, Credential, or Variable management mechanisms.

How to Choose

ScenarioRecommended Method
GitHub Actions WorkflowGitHub Actions
Electron application buildElectron Builder
MSI / EXE installer package creationAdvanced Installer
General Shell / PowerShell automationSignTool CLI
Windows software with native KSP supportWindows Provider
Developing your own signing processAPI Integration

If the build system can directly invoke command-line programs, SignTool CLI can be used; if the tool already provides a standard Windows KSP/CSP interface, the corresponding Windows Provider integration method should be preferred.