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:
| Parameter | Required | Default value | Description |
|---|---|---|---|
access-key | Yes | - | sslTrus Access Key |
access-secret | Yes | - | sslTrus Access Secret |
cert-code | Yes | - | Code signing certificate ID |
files | Yes | - | File path to be signed |
nicsrs | No | false | Whether to use the NICSRS service |
dry-run | No | false | Use a local test certificate to perform test signing |
timestamp-rfc3161 | No | auto | RFC 3161 timestamp server |
description | No | - | Program description written into the Authenticode signature |
description-url | No | - | 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:
| File | Signature |
|---|---|
app.exe | 1 time |
helper.dll | 1 time |
uninstall.exe | 1 time |
installer.msi | 1 time |
| Total | 4 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
| Scenario | Recommended Method |
|---|---|
| GitHub Actions Workflow | GitHub Actions |
| Electron application build | Electron Builder |
| MSI / EXE installer package creation | Advanced Installer |
| General Shell / PowerShell automation | SignTool CLI |
| Windows software with native KSP support | Windows Provider |
| Developing your own signing process | API 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.