The sign command signs one or more files using a certificate held on the Signotaur server. The private key never leaves the server. It signs Windows executables and installers, NuGet and VSIX packages, PowerShell scripts, Apple configuration profiles, Remote Desktop files, ClickOnce and VSTO manifests, PDF and XML documents, and archives, choosing the right signature format for each file automatically.
SignotaurTool.exe sign [options] <files>
A list of file paths to sign. You can specify individual file paths or use wildcards to match multiple files. This parameter supports the following wildcard patterns:
*: Matches zero or more characters within a file name. For example, *.exe will match all executable files in the specified directory.?: Matches a single character. For instance, file?.dll will match file1.dll, file2.dll, but not file12.dll.**: Indicates a recursive search across all subdirectories. For example, **/*.exe will match all .exe files found in the current directory and all its subdirectories.!: Identifies an exclude pattern. This must be at the start of the pattern. It must be used in conjunction with a normal include pattern. For instance, the two patterns *.dll and !*.Test.dll will match all .dll files found in the current directory excluded all test dlls, that is file1.dll, file2.dll, but not file1.Test.dll.Examples:
*.exe: Matches all executable files in the specified directory.C:\Projects\**\*.dll: Matches all dynamic link library files in the C:\Projects directory and any of its subdirectories.C:\MyFiles\file?.exe: Matches any executable files that start with "file" followed by a single character.!*.pdb: Matches all debug files in the specified directory from the current match.Wildcard patterns only search within the directory path you provide, so make sure the path points to the correct folder. To sign a large number of files, consider using --file-list to supply a text file listing the file paths instead.
When signing ClickOnce (.application) or VSTO (.vsto) files, you can specify which dependency files should be signed using content patterns. Use a colon (:) to separate the root file pattern from the content patterns. See ClickOnce and VSTO Signing.
Every option, in the order the reference below documents them. Two options are always required: a way to identify the certificate (Certificate Selection) and --file-digest.
| Option | What it does | Group |
|---|---|---|
-s, --sign-server |
Signotaur server URL | Authentication |
-a, --api-key |
API key for the server | Authentication |
--af, --api-key-file |
Read the API key from a file | Authentication |
--akn, --api-key-name |
Variable name holding the API key | Authentication |
--fe, --fail-if-expiring-within |
Fail if the API key expires soon | Authentication |
-t, --thumbprint |
Select the certificate by thumbprint | Certificate Selection |
-l, --label |
Select the certificate by label | Certificate Selection |
--sb, --subject |
Select the certificate by subject | Certificate Selection |
--ac, --additional-certs |
Add certificates to the signature block | Certificate Selection |
--fl, --file-list |
Read the file list from a file | Input Files |
-b, --base-directory |
Base directory for relative paths | Input Files |
--format |
Force a signature format for every file | Format Selection |
--dt, --detached |
Write a separate signature file | Detached Signatures |
--sf, --signature-file |
Where to write the detached signature | Detached Signatures |
--lv, --level |
AdES signature level | Document Signing |
--cl, --cades-level |
CAdES level (prefer --level) |
Document Signing |
--ce, --cades-encoding |
CAdES encoding, DER or Base64 | Document Signing |
--cm, --cades-mode |
CAdES detached or enveloping | Document Signing |
--xp, --xades-placement |
XAdES enveloped, detached or enveloping | Document Signing |
--xl, --xades-level |
XAdES level (prefer --level) |
Document Signing |
--pl, --pades-level |
PAdES level (prefer --level) |
Document Signing |
--pv, --pades-visible |
Draw a visible signature appearance | Document Signing |
--pp, --pades-page |
Page to attach the signature to | Document Signing |
--pr, --pades-rect |
Appearance rectangle | Document Signing |
--prsn, --pades-reason |
Reason text in the appearance | Document Signing |
--ploc, --pades-location |
Location text in the appearance | Document Signing |
--pfont, --pades-font |
Font to embed in the appearance | Document Signing |
--pimg, --pades-image |
Image drawn in the appearance | Document Signing |
--ppwd, --pades-password |
Open password for an encrypted PDF | Document Signing |
--px, --pades-xref |
Cross-reference style | Document Signing |
--uf, --unsupported-file-types |
What to do with unrecognised files | Unsupported File Types |
-d, --description |
Description embedded in the signature | Signature Metadata |
--du, --description-url |
URL for an expanded description | Signature Metadata |
--an, --app-name |
Application name for ClickOnce and VSTO | Signature Metadata |
--fd, --file-digest |
Required. Digest algorithm | Digest and Page Hashing |
--ph, --page-hashing |
Generate page hashes | Digest and Page Hashing |
--nph, --no-page-hashing |
Suppress page hashes | Digest and Page Hashing |
--tr, --timestamp-server |
RFC 3161 timestamp server URL | Timestamping |
--td, --timestamp-digest |
Timestamp digest algorithm | Timestamping |
--fb, --fallback-timestamp-server |
Timestamp servers to try on failure | Timestamping |
--st, --separate-timestamp |
Timestamp in a second step | Timestamping |
--vc, --verify-cert-chain |
Verify the chain before signing | Signature Validation |
--rm, --revocation-mode |
How revocation is checked | Signature Validation |
--ir, --ignore-untrusted-root |
Allow an untrusted root | Signature Validation |
--sl, --strict-lifetime |
Enforce validity strictly when verifying | Signature Validation |
--as, --append-signature |
Add a signature without replacing | Signing Behaviour |
--sha1, --add-sha1-signature |
Dual-sign for legacy Windows | Signing Behaviour |
--vf, --verify |
Verify the signature after signing | Signing Behaviour |
--ss, --skip-signed |
Skip files already signed | Signing Behaviour |
--au, --allow-untrusted |
Accept an untrusted Signotaur server | Signing Behaviour |
--auc, --allow-untrusted-crl |
Accept an untrusted revocation endpoint | Signing Behaviour |
--cf, --continue-on-fail |
Keep going after a file fails | Signing Behaviour |
--asu, --auto-self-update |
Update the tool before signing | Updating |
--um, --update-mode |
When an update is considered new | Updating |
--wp, --warn-wrong-purpose |
Warn instead of failing on a wrong purpose | Certificate Requirements |
--nmg, --no-mstsc-guidance |
Suppress the post-sign RDP guidance | Output and Diagnostics |
--encoding |
Console output encoding | Output and Diagnostics |
--theme |
Console colour theme | Output and Diagnostics |
--nc, --no-colour |
Disable coloured output | Output and Diagnostics |
-v, --verbose |
Verbose logging | Output and Diagnostics |
--nb |
Hide the banner | Output and Diagnostics |
--rt, --request-timeout |
Server request timeout | Miscellaneous |
-m, --max-degree-of-parallelism |
Concurrent signing operations | Miscellaneous |
--help |
Show help for this command | Miscellaneous |
Every input file is routed to a signature format before anything is signed. The table below is the whole mapping. For how each format is constructed, see Signature Formats by File Type.
| Input | Signed as | Where the signature goes |
|---|---|---|
.exe, .dll, .msi, .msix, .cab, .cat, .sys, .ocx, .vbs, .winmd and the other PE and installer formats |
Authenticode | Inside the file |
.ps1, .psm1, .psd1, .ps1xml, .cdxml |
Authenticode | Inside the file |
.mobileconfig, .mobileprovision, .provisionprofile |
CMS/PKCS#7 | Wrapped around the content |
.nupkg |
NuGet | Inside the package |
.vsix |
VSIX (OPC XML) | Inside the package |
.application, .manifest, .vsto |
ClickOnce and VSTO | Inside the manifests |
.rdp |
RDP | Inside the file, as a signature:s: line |
.pdf |
PAdES | Inside the PDF |
.xml |
XAdES | Inside the XML by default |
.zip, .7z, .tar, .gz, .tgz, .bz2, .xz, .iso, .img, .vhd, .vhdx |
Detached CMS | A separate <file>.p7s |
| Anything else | Decided by --unsupported-file-types |
Depends on the action chosen |
The routing decision is made like this:
--format names a format other than Auto, that format is forced for every input file, and the rest of this list does not apply.--detached extends detached output to other file types.--unsupported-file-types.CAdES is the exception to the table: it has no extension of its own, so it is only produced by asking for it with --format CAdES, or by giving a --level with detached output.
Because step 2 tests the bytes rather than the name, staged binaries emitted by build tools sign correctly with no extra options. The .tmp files InstallShield hands to a signing step are the common case: they are PE images, so they take an Authenticode signature without needing --unsupported-file-types UseAuthenticodeSigning.
-s, --sign-server <URL>
The URL of the Signotaur server that will handle the signing operation. Required unless provided via the SIGNOTAUR_SERVER environment variable or configuration file.
-a, --api-key <APIKey>
Required (unless using --api-key-file, environment variable, or config file). Specifies the Signotaur API key needed to authenticate with the Signotaur service.
--af, --api-key-file <Path>
Path to file containing API key (alternative to --api-key). The file can be a plain text file containing just the API key, or a dotenv file with SIGNOTAUR_API_KEY=<key> format. This is more secure than passing the key via command line as it doesn't appear in shell history.
--akn, --api-key-name <VarName>
Specifies the variable name for reading the API key from an environment variable or dotenv file (default: SIGNOTAUR_API_KEY). Use this to specify a custom environment variable name or to read a specific variable from a dotenv file when using --api-key-file.
--fe, --fail-if-expiring-within <Duration>
Fail if API key expires within specified duration. Prevents signing with keys that are about to expire. Duration format examples: 7d (7 days), 24h (24 hours), 30d (30 days), 1w (1 week), 2w (2 weeks).
API Key Resolution Priority:
--api-key (command line argument)--api-key-file (file path)SIGNOTAUR_API_KEY or custom name via --api-key-name)For detailed workflows on securing and managing API keys via CLI, see API Key Management.
Server URL Resolution:
The server URL can be provided via:
--sign-server (command line argument)SIGNOTAUR_SERVER environment variablesignServer key)One of --thumbprint, --label, or --subject is required to identify the signing certificate. If multiple options are provided, they are evaluated in priority order: thumbprint → label → subject.
-t, --thumbprint <Thumbprint>
Specifies the certificate thumbprint to be used for signing. You can obtain this thumbprint from the Signotaur certificate page. This provides the most specific certificate identification (exact match).
-l, --label <LABEL>
Certificate label for simplified certificate selection. Labels are user-friendly identifiers (e.g., "production", "test") assigned to certificates in the Signotaur server admin interface. When multiple non-expired certificates share the same label, the certificate with the latest expiration date is automatically selected. This allows you to renew certificates without updating your build scripts - simply assign the same label to the new certificate. Case-insensitive matching is used.
--sb, --subject <Subject>
Specifies the certificate subject. This is the least specific option. If multiple certificates with the same subject exist, the operation will fail with an error.
--ac, --additional-certs <CertList>
Adds additional certificates from file paths to the signature block. You can provide a comma-separated list of certificate file paths. This is useful for including intermediate or root certificates that may be necessary for validation.
The certificate must also be marked for the kind of artefact being signed. See Certificate Requirements.
--fl, --file-list <FileName>
Specifies the path to a file containing a list of files to sign. This is useful for batch signing multiple files without specifying them individually on the command line.
Each line in the file must follow this format:
FilePath|Description|URL|ApplicationName
*, ?, **) to match multiple files. The tool will interpret each path just as it does for the Files parameter. For ClickOnce/VSTO files, you can use the content pattern syntax (:) to filter dependencies (e.g., MyApp.application:*.dll:*.exe).-d or --description option for the specified file or matching files.-du or --description-ul option for the specified file or matching files.--an or --app-name option for the specified file or matching files.Quoting and escaping rules
|) or a double quote (").|) or a double quote ("), it must be enclosed in double quotes ("").\").\) must be escaped (\\) inside a quoted field, but remain unchanged if unquoted.Example entries
C:\Folder\*.exe
C:\Users\user\*.dll|Sample description
"C:\Projects\**\file.dll"|"A \"quoted\" description"|"http://example.com"
"C:\Dev\drivers\*.sys"|"System drivers"|http://example.com
"*.dll"|"This description contains a | pipe character"|http://example.com
"E:\Publish\App\app.exe"|Description with spaces|https://example.com
-b, --base-directory <Directory>
Sets the base directory for resolving relative file paths.
--format <Format>
Selects the signature format for every input file. Values: Auto (default), Authenticode, Cms, NuGet, Vsix, Rdp, ClickOnce, XAdES, PAdES, CAdES.
Auto detects by extension and content, as described in What Gets Signed, and How.
Any other value forces that signer for every input file, overriding detection. --format cms CMS-signs even an .exe or .nupkg; --format authenticode, --format nuget, --format vsix and --format rdp force those signers in the same way. CAdES must be selected here, because it has no file extension of its own.
ClickOnce is the exception: it is detection-only and does not force.
Forcing a format changes what the certificate must be marked for, because the purpose check follows the signature each file actually receives. See Certificate Requirements.
Some artifacts have no standard for an embedded signature, most notably archives and disk images. Signing these in place (for example with --unsupported-file-types UseCMSSigning) would wrap the whole file in a PKCS#7 envelope and destroy the original. Instead, Signotaur writes a detached CMS/PKCS#7 signature to a separate .p7s file, leaving the original byte-for-byte unchanged.
Archive and disk-image formats are signed this way automatically, with no extra flags:
SignotaurTool sign archive.zip --fd SHA256 -a <api-key> -t <thumbprint>
This signs archive.zip and writes the signature to archive.zip.p7s alongside it; archive.zip itself is not modified.
--dt, --detached
Extend detached signing to file types that have no embedded-signature format (for example .txt, .json, or arbitrary binaries). The archive and disk-image formats do not require this flag. Known formats (PE, MSI, NuGet, VSIX, RDP, ClickOnce, .mobileconfig) always use their native embedded signatures and ignore --detached.
--sf, --signature-file <Pattern>
Override the detached signature output path. By default a <file>.p7s signature file is written next to each signed file.
Exact path (no placeholder): only valid when signing a single file. The path can be a bare filename (written to the current directory) or include a directory:
SignotaurTool sign archive.zip --signature-file archive.sig ...
SignotaurTool sign archive.zip --signature-file C:\sigs\archive.sig ...
Placeholder pattern (batch): substituted for each file, so it works across wildcards and --file-list:
{name}: the file's full name including its extension (for example archive.zip){name-no-ext}: the file's name without its final extension (for example archive){rel-path}: the file's path relative to the base directory, including the filename (for example src\a\archive.zip). This recreates the input folder structure under the output directory.The pattern can write signatures to the current directory or collect them under a directory:
SignotaurTool sign *.zip --signature-file {name}.p7s ...
SignotaurTool sign *.zip --signature-file sigs\{name}.p7s ...
The first writes archive.zip.p7s, report.zip.p7s, and so on; the second writes sigs\archive.zip.p7s, sigs\report.zip.p7s. (Using {name-no-ext} instead of {name} would write archive.p7s / sigs\archive.p7s.)
When signing a recursive tree, {name} would make files with the same name in different folders collide. Use {rel-path} to keep them distinct:
SignotaurTool sign src\**\*.zip --signature-file sigs\{rel-path}.p7s ...
signs src\a\archive.zip and src\b\archive.zip to sigs\src\a\archive.zip.p7s and sigs\src\b\archive.zip.p7s respectively. The base directory is the directory the command runs in, or --base-directory when set. So --base-directory src would instead write sigs\a\archive.zip.p7s. A file located outside the base directory falls back to just its filename (with a warning), so the output can never escape the pattern's root.
Any directory in the output path is created automatically if it does not already exist, including nested directories.
The .p7s signature file is a standard CMS/PKCS#7 SignedData structure. It can be verified with SignotaurTool verify or any standards-compliant tool, for example:
openssl cms -verify -binary -inform DER -in archive.zip.p7s -content archive.zip -CAfile root.pem
Signotaur signs PDF, XML and other documents using the AdES formats: PAdES, XAdES and CAdES. For a task-oriented guide see Signing Documents; this section is the option reference.
Producing a document signature needs a server with an Enterprise licence. Without one the document files in a batch are refused (code files still sign) and the run ends with exit code 87. See Signing Documents.
--lv, --level <Level>
The AdES signature level, in plain language. Values: baseline (or B, the default), timestamped (T), long-term (LT), archival (LTA). Case-insensitive; hyphens and underscores are ignored.
timestamped and above require --timestamp-server, or the command fails validation and nothing is signed. long-term and archival additionally collect revocation evidence (OCSP, falling back to CRL) from the signing certificate's AIA/CDP addresses; a certificate with none produces a warning and a signature with no embedded evidence. If those addresses are HTTPS and served with a certificate the signing machine does not trust, add --allow-untrusted-crl.
This is the main level control. It applies to whichever AdES format each file uses, and overrides --cades-level, --xades-level and --pades-level. On a non-AdES file it is ignored, with a per-file warning.
--cl, --cades-level <Level>
Bes (default), T, Xl (long-term), or Lta (archival). T and above require --timestamp-server. Prefer --level.
--ce, --cades-encoding <Encoding>
Der (default, binary) or Base64.
--cm, --cades-mode <Mode>
Detached (default) keeps the content in the original file and writes a separate .p7s; Enveloping carries a copy of the content inside the signature and writes a single file with the .p7m extension.
--xp, --xades-placement <Placement>
Enveloped (default) adds the signature inside the .xml; Detached writes a separate <file>.sig and leaves the original untouched; Enveloping wraps a copy of the XML inside the signature. --detached selects the detached placement, so this option is rarely needed.
--xl, --xades-level <Level>
B_B (default), B_T, B_LT or B_LTA. B_T and above require --timestamp-server. Prefer --level.
--pl, --pades-level <Level>
B_B (default), B_T, B_LT or B_LTA. All four are supported. B_T and above require --timestamp-server. Prefer --level.
--pv, --pades-visible
Draw a visible signature appearance. The default is an invisible (but fully valid) signature.
--pades-rect, --pades-reason, --pades-location, --pades-font and --pades-image are all drawn into that appearance. Without --pades-visible there is nothing to draw them in, so they are ignored with a warning. --pades-page is the exception: the signature is attached to that page whether it is drawn or not.
--pp, --pades-page <Page>
The page to draw the appearance on, counting from 1. Default 1.
--pr, --pades-rect <Rect>
The appearance rectangle as "x,y,width,height" in PDF points, measured from the bottom-left corner of the page. Default 36,36,220,64.
--prsn, --pades-reason <Reason> and --ploc, --pades-location <Location>
Reason and location text drawn in the appearance box.
--pfont, --pades-font <FontPath>
Path to a TrueType or OpenType font to embed. Required for text outside the Latin-1 character set.
--pimg, --pades-image <ImagePath>
Path to a JPEG or PNG drawn in the appearance box.
--ppwd, --pades-password <Password>
The user (open) password for signing a PDF protected by the standard security handler.
--px, --pades-xref <Style>
Cross-reference style for the incremental update: Auto (default, matching the original PDF), Classic (table) or Stream.
PAdES has no detached form. Under --format Auto, a .pdf in a batch that requests detached output (via --detached or --signature-file) is written as a detached CAdES .p7s when a --level is given, or a plain CMS .p7s otherwise, with a warning that no PDF reader will show a signature. Combining --detached with an explicit --format pades is an error rather than a downgrade.
There is no --pades-contact option, and no option for CAdES parallel signatures: each run produces a single signer. AdES behaviour is command-line only; there are no client configuration-file keys for it.
Everything in What Gets Signed, and How is signed automatically. This option governs what happens to input that matched none of it.
--uf, --unsupported-file-types <Action>
--continue-on-fail to sign the rest of the batch around it.CMS/PKCS#7 signing wraps the entire file content in a cryptographic envelope. This is appropriate for formats that expect CMS wrapping (such as Apple .mobileconfig profiles) but should not be used for executable formats like .exe or .dll where Authenticode embeds the signature within the existing file structure. To sign a file of any type without altering it, use --detached instead.
UseAuthenticodeSigning and UseCMSSigning both change what the certificate must be marked for. See Certificate Requirements.
-d, --description <Description>
Specifies a description of the signed content. This description will be embedded in the signature and should provide context about the content being signed.
--du, --description-url <URL>
Specifies a URL for an expanded description of the signed content. This URL can point to a webpage or document that provides more detailed information about the signed files.
--an, --app-name <Name>
Specifies an application name - only used when signing ClickOnce/VSTO manifests.
--fd, --file-digest <Algorithm>
Required. Specifies the file digest algorithm to use for creating file signatures. Supported algorithms include: SHA256, SHA384, SHA512.
--ph, --page-hashing
Enables the generation of page hashes for executable files if supported by the file type. This is useful for ensuring the integrity of the executable's pages and can help detect tampering.
--nph, --no-page-hashing
Suppresses the generation of page hashes for executable files if supported. Use this option if you do not want to include page hashes in the signature.
--tr, --timestamp-server <TimeStampServer>
Specifies the URL of the RFC 3161 timestamp server. Time stamping is important for proving when a file was signed. If this option is not included, the signed file will not be timestamped. A warning will be generated if timestamping fails.
--td, --timestamp-digest <DigestAlgorithm>
Specifies the digest algorithm used by the RFC 3161 timestamp server. This option is required if the --tr option is provided. Supported algorithms include SHA256, SHA384, and SHA512.
--fb, --fallback-timestamp-server <FallbackTimeStampServers>
Specifies one or more URLs for RFC 3161-compliant timestamp servers to use as fallbacks if the primary timestamp server (--tr) fails. Provide multiple servers by repeating this option. The servers are tried sequentially, stopping at the first successful response.
--st, --separate-timestamp
Enables a separate time-stamping step after signing. Supported for Authenticode (.exe, .dll, .msi, .cat, etc.), CMS (.mobileconfig, .mobileprovision, .provisionprofile), detached CMS signature files (.p7s), NuGet (.nupkg), VSIX (.vsix), and RDP (.rdp) files. ClickOnce/VSTO manifests are always timestamped inline; post-sign timestamping is not supported for manifests because the timestamp is embedded inside the manifest's strong-name-signed scope.
Automatically activated when any fallback timestamp servers (--fb) are specified.
Failure behaviour differs between inline and separate modes:
--st (inline mode): signing and timestamping are atomic. If the TSA fails, the file on disk is unchanged.--st (separate mode): the file is signed first, then timestamped in a second step. If the TSA fails, the file is left on disk signed but not timestamped; the signing command exits with a timestamp error. You can add a timestamp later without re-signing by running the timestamp subcommand.The AdES formats embed their timestamp as they sign, so --separate-timestamp does not apply to a document batch.
--vc, --verify-cert-chain
Verifies the certificate chain before signing. If not set, the chain is not verified (default). Enables --revocation-mode and optionally --ignore-untrusted-root.
--rm, --revocation-mode <Mode>
Specify the revocation check mode when building the certificate chain. Only used during signing when --verify-cert-chain is enabled.
By default, the chain-building process may try to check the certificate status against online Certificate Revocation Lists (CRLs) or Online Certificate Status Protocol (OCSP) responders. If these URLs are inaccessible or slow to respond, possibly due to firewall restrictions, then changing the revocation mode can improve signing performance. The parameter accepts the following <Mode> values:
Note: Software signed with a revoked certificate may trigger trust warnings or be blocked by operating systems. We therefore recommend checking and adjusting your firewall settings first. Ensure that it permits outbound HTTP (port 80) and HTTPS (port 443) traffic to the CRL and OCSP URLs specified in your certificates.
--ir, --ignore-untrusted-root
Ignore untrusted root errors. When signing, it allows certificate chains that do not terminate in a trusted root (requires --verify-cert-chain). When verifying, this skips errors caused by unknown or self-signed root certificates.
--sl, --strict-lifetime
Strictly enforce signature validity to the certificate's validity period when verifying and a timestamp is present.
--as, --append-signature
Appends this signature to the file. If no primary signature exists, this signature will become the primary one. This is useful for signing files multiple times without overwriting existing signatures.
--sha1, --add-sha1-signature
Adds an additional SHA-1 signature for dual-signing to support legacy Windows versions. This allows files to be trusted on older operating systems that do not support modern SHA-256 or higher digest algorithms, while maintaining a primary signature with a stronger algorithm.
Dual signing requires an RSA code-signing certificate. ECDSA certificates cannot be used with --sha1: the secondary signature fails to append with an E_INVALIDARG error, and ECDSA signatures are not validated by Windows versions older than Windows 8 in any case, so no legacy compatibility is gained. See Certificate recommendations for more detail.
--append-signature and --add-sha1-signature have no effect alongside --skip-signed, since that skips the file entirely. Appending a signature is only officially supported on Windows Server 2022 and Windows 11 or later, and may not work reliably on Windows 10.
--vf, --verify
Verifies the signature after signing to ensure it is valid.
--ss, --skip-signed
Skips any files that have been previously signed.
--au, --allow-untrusted
Allows signing using a Signotaur server that is bound to an untrusted or invalid certificate. Use this option with caution, as it may expose you to security risks.
--auc, --allow-untrusted-crl
Allows the long-term signature levels to download revocation data (CRL and OCSP) from an HTTPS distribution point that is bound to an untrusted or invalid certificate.
Whether you need it depends on the CA that issued your signing certificate, not on Signotaur. It applies when that CA publishes revocation data over HTTPS using a TLS certificate the signing machine does not trust, which any internal CA may do. Signotaur's own Internal CA serves its validation endpoints over plain http://, so certificates it issues do not normally need this.
This is separate from --allow-untrusted, which covers only the connection to the Signotaur server: relaxing trust for one does not relax it for the other. It only affects --level long-term and --level archival (and the equivalent per-format levels), because those are the levels that fetch revocation data. Use it with the same caution.
This option applies while signing. It cannot help anyone verifying the signature later, because that check runs through the operating system's own certificate handling, which has no equivalent option: an HTTPS distribution point must be trusted by the machine's certificate store, or verification reports CERT_E_REVOCATION_FAILURE. Install the issuing CA's root certificate on the verifying machine, or have the CA publish revocation data over plain http://, which is the usual practice precisely because it avoids this circularity.
--cf, --continue-on-fail
Continues signing subsequent files even if an error occurs while signing a file. This option is useful for batch signing scenarios where you want to attempt to sign all files regardless of individual failures.
--asu, --auto-self-update
Automatically checks for and installs updates before signing.
If an update is installed, the updated version restarts with the same command-line arguments, excluding this option.
--um, --update-mode <Mode>
Choose 'Version' to update to every new release, or 'SourceHash' (default) to update only when the source code hash differs (e.g. when there are changes).
--nmg, --no-mstsc-guidance
Skip the post-sign Remote Desktop trust-configuration guidance printed after signing .rdp files. Useful in automation / CI where the guidance is just noise. See RDP file signing for details on the guidance output and the recipient-side configuration it explains.
--encoding <Encoding>
Specifies the output encoding. Set to one of UTF8, UTF16, OEMCodePage or CodePage### where ### is the number of the code page to use. Defaults to UTF8.
--theme <Theme>
Specifies the console colour theme. Options are: General (default, suitable for most consoles), Dark (optimized for dark backgrounds), Light (optimized for light backgrounds), or None (disables colours). The default is General.
--nc, --no-colour, --no-color
Disables coloured output entirely. This is useful for CI/CD environments, log files, or systems that don't support ANSI colour codes. Alternatively, you can set the NO_COLOR environment variable to any non-empty value to achieve the same effect (following the no-color.org standard).
-v, --verbose
Enables verbose logging for the signing operation, providing detailed output of the signing process, which can be useful for debugging.
--nb
Hides the banner in the output, which may be useful for scripting or logging purposes where you want a clean output.
--rt, --request-timeout <TimeoutInSeconds>
Specifies the request timeout for server requests in seconds. If the server takes longer than the specified time to respond, the operation will be aborted. Default is 0 for automatic timeout calculation based on number of files
-m, --max-degree-of-parallelism <MDOP>
Specifies the maximum number of concurrent file signing operations. This setting allows you to control the degree of parallelism to optimize performance. The default value is 4, but you can adjust this based on the capabilities of your machine.
--help
Displays help information and usage instructions for this command.
The signing certificate has to permit what you are asking it to do. Signotaur checks that before it signs anything, and by default refuses the run rather than producing a signature nobody will accept.
When the check refuses, nothing is signed and the run ends with exit code 34. Two things are checked, in this order.
Key usage. The certificate's Key Usage extension must permit digitalSignature or nonRepudiation. A key that permits neither is not authorised to produce a signature at all, so it is refused for every file type, and no extended key usage overrides that. A certificate with no Key Usage extension is unrestricted and passes.
Extended key usage. Document formats (XAdES, CAdES, PAdES) require a document-signing EKU (Microsoft, Adobe or RFC 9336) or Email Protection. Code formats (Authenticode, CMS, NuGet, VSIX, RDP, ClickOnce) require the Code Signing EKU. A detached .p7s accepts either of those, because it signs file content of a kind it cannot determine, so any content-signing purpose covers it; only a certificate restricted to non-content purposes, such as TLS authentication or time stamping, is refused.
A certificate with no EKU extension at all, or with the Any Purpose usage, is treated as covering every purpose, so it is normally neither refused nor warned about. The one exception is a certificate with no EKU extension whose key usage is nonRepudiation without digitalSignature. That is the ETSI document-signing profile, whose key is not authorised to sign code, so it is refused for the code formats while still signing the document formats.
Whether it refuses or warns, the message lists the extended key usages the certificate actually carries, so the cause is visible without inspecting the certificate yourself.
The purpose required follows the signature each file actually receives, not the file's extension. --format and --unsupported-file-types UseAuthenticodeSigning therefore change what the certificate must carry: a file routed to Authenticode needs the Code Signing EKU whatever it is called, and --detached with a --level produces a CAdES document signature that needs a document-signing usage. Files skipped by --unsupported-file-types Ignore, or failed by its default, are never signed and so require nothing.
--wp, --warn-wrong-purpose
Only warn, instead of failing, when the signing certificate is not marked for the kind of artefact being signed. The files are signed and the run continues.
Document signing additionally requires an Enterprise-licensed server, which is a separate check that --warn-wrong-purpose does not affect; see Signing Documents.
For what makes a certificate acceptable in the first place, see Code-Signing Certificates and Document-Signing Certificates.
Each per-format option reaches only its own signer, so one naming a format absent from the batch does nothing. Rather than dropping it in silence, sign warns once per run and continues:
--cades-*, --xades-* or --pades-* option when no file in the batch is signed in that format.--pades-rect, --pades-reason, --pades-location, --pades-font, --pades-image) without --pades-visible. --pades-page is not in this group: the signature is attached to that page whether it is drawn or not.--pades-password on a PDF that turns out not to be encrypted.--level alongside --cades-level, --xades-level or --pades-level, naming the per-format value it overrides.--detached or --signature-file with --cades-mode Enveloping or --xades-placement Enveloping, where the placement wins and no separate signature file is written.--timestamp-digest or --fallback-timestamp-server without --timestamp-server.--separate-timestamp on a document batch: XAdES, PAdES and CAdES embed their timestamp as they sign.--description and --description-url on a batch with no Authenticode file, as they are carried in an Authenticode-only attribute.What counts is whether you supplied the option, not what you set it to: --cades-mode Detached on a batch with no CAdES file is reported even though Detached is the default, because typing it still achieved nothing. An option you did not supply is never reported.
Sign multiple files with a specified thumbprint:
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 file1.exe file2.dll
Sign files using certificate label (recommended for CI/CD):
SignotaurTool.exe sign --api-key-file %USERPROFILE%\.signotaur\api_key.txt -s https://signotaur.example.com --label production --fd SHA256 *.exe
Sign files with API key from file and expiration check:
SignotaurTool.exe sign --api-key-file /path/to/key.txt --fail-if-expiring-within 7d -s <SignServer> --label production --fd SHA256 file1.exe
Sign files with timestamping:
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 file1.exe file2.dll
Sign files with timestamping and verification:
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 --vf file1.exe file2.dll
Sign an Apple .mobileconfig profile (automatically uses CMS/PKCS#7):
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 profile.mobileconfig
Sign a NuGet package (automatically detected):
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 MyPackage.1.0.0.nupkg
Sign a Visual Studio extension (automatically detected):
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 MyExtension.vsix
Sign a Microsoft Remote Desktop connection file (automatically detected):
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 connection.rdp
Sign a PowerShell script (automatically uses Authenticode):
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --tr <TimeStampServer> --td SHA256 Deploy.ps1
Sign an unrecognised file type using CMS/PKCS#7:
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --uf UseCMSSigning config.dat
Sign an archive (automatically written as a detached .p7s):
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 release.zip
Sign a PDF (automatically uses PAdES; requires an Enterprise licence):
SignotaurTool.exe sign -a <APIKey> -s <SignServer> -t <Thumbprint> --fd SHA256 --level timestamped --tr <TimeStampServer> --td SHA256 contract.pdf
Which format each file receives is decided as described in What Gets Signed, and How. This section covers how each signature is constructed.
Authenticode signing covers the following file types: .appx, .appxbundle, .cab, .cat, .cdxml, .dll, .eappx, .eappxbundle, .emsix, .emsixbundle, .exe, .msi, .msix, .msixbundle, .msm, .msp, .mst, .ocx, .ps1, .ps1xml, .psd1, .psm1, .stl, .sys, .vbs, .vxd, .winmd. Additional PE file types are also signed automatically, since detection is by content.
PowerShell scripts and modules: .ps1 (scripts), .psm1 (modules), .psd1 (module manifests), .ps1xml (format and type definitions) and .cdxml (cmdlet definition XML) are signed with Authenticode, exactly the same way as an .exe. No PowerShell-specific options are required. For an end-to-end walkthrough covering execution policy, verification with Get-AuthenticodeSignature, and timestamping, see Signing PowerShell scripts.
Apple configuration and provisioning profiles (.mobileconfig, .mobileprovision, .provisionprofile) are signed with CMS/PKCS#7, which wraps the file content in a SignedData envelope. Unrecognised file types can also be CMS-signed with --unsupported-file-types UseCMSSigning.
.zip, .7z, .tar, .gz, .tgz, .bz2, .xz, .iso, .img, .vhd and .vhdx receive a detached CMS/PKCS#7 signature in a separate .p7s file, leaving the original untouched. --detached extends the same treatment to any other file type, and --signature-file controls where the sidecar is written.
NuGet packages (.nupkg) are signed using NuGet-specific signing. The signature is embedded as a .signature.p7s entry inside the package ZIP archive, conforming to the NuGet Package Signing specification. The signature includes:
--tr is specified)Signed packages can be verified with dotnet nuget verify or with SignotaurTool.exe verify.
VSIX packages (.vsix) are signed using OPC (Open Packaging Conventions) XML digital signatures, conforming to the format used by Visual Studio. Signing computes per-part digests with inclusive XML canonicalisation and writes the signature into the package as a signed XML manifest.
Signed packages can be verified with SignotaurTool.exe verify. RFC 3161 timestamping is supported when --tr is specified.
.rdp files (Microsoft Remote Desktop connection files) are signed using Microsoft's RDP file signing format: a detached CMS/PKCS#7 signature wrapped in Microsoft's 12-byte header and embedded into the file itself as a signature:s: line. The output is byte-structurally equivalent to what rdpsign.exe produces and is accepted by Windows Remote Desktop Connection.
After signing, the tool prints a guidance block explaining how recipients' Windows machines need to be configured to accept the signature without a warning dialog. Suppress it with --no-mstsc-guidance. See RDP file signing for the full recipient configuration and troubleshooting.
--tr and --td work for .rdp files and the timestamp is embedded into the CMS in the standard way, but mstsc.exe does not consult the timestamp when validating the signature. Once the signing certificate expires, signed .rdp files revert to the "Caution: Unknown remote connection" dialog regardless of the timestamp. This is a mstsc limitation, not a Signotaur one (Microsoft's own rdpsign.exe has no timestamping support at all). See Timestamping and certificate expiry for the full explanation and recommended approach.
If the input includes a .application file (ClickOnce deployment manifest) or a .vsto file (Visual Studio Tools for Office add-in manifest), the sign command automatically:
.vsto filesSee ClickOnce and VSTO Signing for detailed information about content filtering and application-specific options.
.xml files are signed as XAdES and .pdf files as PAdES. CAdES has no extension of its own and is selected with --format CAdES, or produced when a --level is given with detached output. All three are ETSI Advanced Electronic Signatures and support four levels, from a baseline signature to an archival one that stays verifiable after the signing certificate expires. The options are in Document Signing (AdES); for a task-oriented guide see Signing Documents.
The following exit codes indicate the result of the operation performed by SignotaurTool.exe sign. The most common failures are 4 Failure (server, gRPC, or unsupported-file errors), 47 TimeStampError (when --timestamp-server is specified), and chain-validation codes (20 UntrustedRoot, 21 CertificateExpired, 41 CertificateChaining, etc.) when --verify-cert-chain or --verify is in use. Codes 16–58 reach the sign command via the Windows SignerSignEx3 API for Authenticode files (.exe, .dll, .msi, .cat, .sys, etc.) and via cryptographic exceptions in the managed signers for CMS, NuGet, VSIX, and RDP files. Any HRESULT the Windows API can return is mappable here. Codes 12 AdditionalCertNotFound, 41 CertificateChaining, 43 PlatformNotSupported, 59 ApiKeyExpiring, and 60 InvalidDuration are produced by the sign command directly before any signing pipeline runs. Codes 66–85 cover additional Win32 file-system errors, cryptographic-message errors, and AppX/MSIX packaging errors surfaced when signing .appx/.msix packages.
NotFound, HTTP 404, ERROR_FILE_NOT_FOUND).Cancelled / DeadlineExceeded, E_ABORT).Unauthenticated / PermissionDenied, HTTP 401, E_ACCESSDENIED).1, 2, 3, 6, 64).InvalidArgument, E_INVALIDARG).--additional-certs could not be found (CRYPT_E_NOT_FOUND).--file-list file.--verify was specified but no signature was produced or could be located (TRUST_E_NOSIGNATURE).--ignore-untrusted-root.36 CertificateRevocationFailure.--append-signature on Windows versions older than Windows 11 / Windows Server 2022.--verify.--verify-cert-chain and --revocation-mode Online are in use.--fail-if-expiring-within.--fail-if-expiring-within value is not a valid duration (use forms such as 7d, 24h, 1w).--api-key with --api-key-file, or --detached with --format pades. Nothing is signed.Unavailable). Distinct from 4 Failure so CI/CD pipelines can retry-on-transient.--verify.AppxBlockMap.xml inside the package is missing or invalid (APPX_E_INVALID_BLOCKMAP).AppxManifest.xml inside the package is malformed or does not conform to the schema (APPX_E_INVALID_MANIFEST).AppxManifest.xml, AppxBlockMap.xml, or [Content_Types].xml (APPX_E_MISSING_REQUIRED_FILE).AppxBlockMap.xml does not match the actual content of the file (APPX_E_BLOCK_HASH_INVALID).Limits.GrpcRateLimit.Typically a more specific message will be displayed before an error exit code is returned.
baseline.--format pades.Server Connection Issues:
Signotaur server URL is reachable.--allow-untrusted.Certificate Not Found:
File Signing Errors: