Batch Signing Guide
Sign entire build directories with glob patterns, parallel workers, auto-verification, and resume-on-failure. All files share a single credential session.
Quick start
npm install -g @qwickcert/cli qwick auth login qwick sign "dist/**/*.exe" --verify
This signs every .exe file in dist/ recursively and verifies each signature afterward.
File patterns
The CLI uses fast-glob for pattern matching, supporting recursive globs, brace expansion, and negation.
Recursive globs
qwick sign "dist/**/*.exe" # all .exe in dist/ and subdirectories qwick sign "build/**/*.dll" # all .dll in build/ tree
Brace expansion
qwick sign "dist/**/*.{exe,dll,msi}" # multiple extensionsExclude patterns
Use excludePatterns in your .qwickrc.json to skip files by pattern:
{
"files": ["dist/**/*.exe"],
"excludePatterns": ["*test*", "*debug*"]
}Project configuration (.qwickrc.json)
Store all signing settings in a config file so your team can run qwick sign with no arguments.
qwick config init
{
"project": "my-app",
"organization": "acme-corp",
"files": ["dist/**/*.exe", "dist/**/*.dll"],
"excludePatterns": ["*test*"],
"timestampUrl": "http://timestamp.acs.microsoft.com",
"digestAlgorithm": "sha256",
"parallel": 4,
"verify": true,
"outputFormat": "text"
}See the CLI Reference for the full schema and precedence order.
Parallel signing
Run multiple SignTool processes concurrently to speed up large batch jobs. All workers share the same credential session.
qwick sign "dist/**/*.exe" --parallel 4
Worker count recommendations
- 1-5 files:
--parallel 1(default, no overhead) - 5-20 files:
--parallel 2-4 - 20+ files:
--parallel 4-8 - Maximum:
--parallel 16
Auto-verify
The --verify flag runs signtool verify /pa on every signed file. If any verification fails, the CLI exits with a non-zero code.
qwick sign "dist/**/*.exe" --verify # Output: # ✓ Signed 12 files in 18.4s — all signatures verified
You can also enable this permanently in .qwickrc.json:
{ "verify": true }Resume on failure
If signing is interrupted (crash, network error, Ctrl+C), the CLI saves progress to .qwick-signing-state.json. Resume where you left off:
# First attempt — interrupted after 5/20 files qwick sign "dist/**/*.exe" --progress # Resume — skips the 5 already-signed files qwick sign "dist/**/*.exe" --resume
Don't forget your .gitignore
Add .qwick-signing-state.json to your .gitignore — it's a temporary file that should not be committed.
CI/CD integration
Use --output json for machine-readable output in CI pipelines. The exit code is the canonical success/failure signal.
qwick sign "dist/**/*.exe" --output json --verify
The JSON output includes per-file results, timing, the operation ID, and verification status.
GitHub Actions example
- name: Sign build output
run: |
npx @qwickcert/cli sign "dist/**/*.{exe,dll}" \
--parallel 4 \
--verify \
--output json > signing-results.json
env:
QWICK_API_KEY: ${{ secrets.QWICK_API_KEY }}
QWICK_PROJECT: my-appBest practices
Mind the credential TTL
Signing credentials expire after 10 minutes. For very large batches (100+ files), use --parallel 8 or higher to stay within the window.
Add temp files to .gitignore
Add .qwick-signing-state.json to your .gitignore.
Always use --verify in CI
The --verify flag catches silent failures. Make it a default in your .qwickrc.json.
Quote glob patterns in your shell
Always wrap glob patterns in quotes ("dist/**/*.exe") to prevent your shell from expanding them before the CLI sees them.