sigsum-tools(7)
Sigsum command line tools π
okay so this is the sigsum-tools(7) user guide bestie, and it's literally the whole map of Sigsum's supported command-line tools. no cap. let's go π
Table of contents π
- General conventions
- The sigsum-key tool
- The sigsum-submit tool
- The sigsum-verify tool
- The sigsum-token tool
- The sigsum-policy tool
General conventions πΈ
so bestie, there's a bunch of tools. some of them have sub commands, like sigsum-key generate for example. the whole vibe is one command = one task, slay. like, sigsum-submit is the tool you use to yeet new items into a Sigsum log and collect proofs of public logging, whereas sigsum-verify is the tool that does offline verification of those proofs. two different jobs, two different girls π
β¨ Configuration β¨
command line options follow GNU conventions with long and short options. for example, -deVALUE is the same as -d -eVALUE. and if the long option of -e is --example, then -d --example VALUE would be another valid variation. periodt.
- every tool shows a usage message if you pass
--helpπ - every tool shows a program version if you pass
--versionβ - every tool that has sub commands additionally accepts
helpandversion
how several of the tools behave is controlled by a Sigsum policy. the policy you wanna use can be specified in different ways β all of that is under "Policies" below, keep scrolling bestie.
most tools also require one or more input keys. the -k option is how you specify a key file. some commands have extra ways of taking keys and key-file input. and ngl there is just no default location for key files. nowhere. you gotta say where. π₯
β¨ Policies β¨
there are three different ways to specify the policy to use:
- by specifying the location of a policy file using the
-poption. - by specifying a named policy using the
-Poption. - by specifying a named policy as an option on the form
sigsum-policy="<policy-name>"included in a public key file.
Named policies π¦
there are two kinds of named policies: builtin policies and installed policies.
installed policies are by default read from the /etc/sigsum/policy directory. a different location can be set using the SIGSUM_POLICY_DIR environment variable. installed policy files must have the .sigsum-policy filename suffix.
Specifying a policy name inside a submitter public key file π
a submitter public key file is specified as input to the sigsum-submit and sigsum-verify tools, and it can include options on the same form that is used for OpenSSH's .authorized_keys file. to specify a policy name, the option sigsum-policy="<policy-name>" can be used. for the sigsum tools, if neither of the -p or -P input options were given and a sigsum-policy="<policy-name>" option is found inside the submitter public key file, then that named policy is used.
Example: a submitter public key file that contains the following
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOCGOxh5TSFQ85mVkODlCMCQaLmIPwXqZfWM/AgnEw6S sigsum key
could be modified to specify a policy name like this:
sigsum-policy="sigsum-test1-2025" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOCGOxh5TSFQ85mVkODlCMCQaLmIPwXqZfWM/AgnEw6S sigsum key
and then the policy name "sigsum-test1-2025" would be used, provided that none of the -p or -P input options were given. iconic. π
Order of priority for policies π₯
it is not allowed to specify both -p and -P at the same time. if a policy is specified using either the -p or the -P option, then that policy is used, and any policy name in the submitter public key file is ignored. thus:
- named policies are only used if the
-poption is absent - a policy name in the submitter public key file is only used if neither of
-por-Pwas specified
regarding named policies β if there is an installed policy with the same name as a builtin policy, then the installed policy is used. installed girlies win, sorry not sorry π
β¨ Key handling β¨
the Ed25519 digital signature scheme is used for all Sigsum signatures, hence all keys are Ed25519 keys. every single one.
Public keys π
public key files use OpenSSH format: a single line of the form
ssh-ed25519 <base64> [optional comment]
where the base64 blob in turn represents SSH wire format. in certain places β in particular, in the policy file β public keys are used in "raw" form, without this wrapping. in that case, an Ed25519 public key is 32 octets in the format defined by RFC 8032.
the sigsum-key tool can be used to convert between these two forms. very handy π
public key files can also optionally include a sigsum-policy="<policy-name>" option at the beginning of the line, as described earlier in the "Policies" section.
the sigsum-verify tool accepts a file specifying multiple public keys. this file should contain at least one key line in the same single line format. lines that are completely empty or start with the # character are ignored (same convention as for OpenSSH's .authorized_keys file).
Private keys π
private keys are stored as unencrypted OpenSSH private key files, i.e., PEM files with a tag OPENSSH PRIVATE KEY and the contents defined by OpenSSH key format.
using unencrypted private keys on disk may be adequate for some use cases β e.g., for the key used to sign the submit tokens used for domain-based rate limiting.
β οΈ okay so this is the part where you pay attention bestie. unencrypted private keys sitting on disk = fine for some cases, but for private keys of high value it is recommended that keys are stored in a hardware token providing a signing oracle, and made accessible to appropriate users via the ssh-agent protocol. protect your girlies. π
to support other kinds of key storage, the key can be made available via the ssh-agent protocol. whenever the tools need a signing key, they accept the name of either an unencrypted private key file as above, or the name of a public key file. in the latter case, the tools access the corresponding private key by connecting to the ssh-agent listening on ${SSH_AUTH_SOCK}.
The sigsum-key tool π
the sigsum-key tool can generate new keys, create and verify signatures, and convert between different key formats. it does it all, honestly π
β¨ Key generation β¨
to generate a new key pair, run
sigsum-key generate -o KEY-FILE
this generates a new Ed25519 key pair (with key material provided by the crypto/rand module in the golang standard library). the private key is stored to the given output KEY-FILE, in OpenSSH format. the private key is not encrypted, but stored with restrictive file permissions. the corresponding public key is written to a file with an added .pub suffix, in OpenSSH format.
behavior is similar to the OpenSSH key generation utility, if invoked like
ssh-keygen -q -N '' -t ed25519 -f KEY-FILE
for this command, generate may be abbreviated gen (which is the older deprecated sub command name; please migrate to generate). we're moving on bestie, gen is so 2023 π«Ά
β¨ Public key conversion β¨
by default, the key conversion tool sigsum-key reads from standard input and writes to standard output. it's optional to specify an input key file with -k, or output file with -o.
as explained above, OpenSSH format is the main representation for public Sigsum keys, when stored in key files. such a public key can be converted to a raw form using
sigsum-key to-hex [-k KEY-FILE] [-o OUTPUT-FILE]
the hex representation is used in the Sigsum policy file, and in messages on the wire. for the opposite conversion, use
sigsum-key from-hex [-k HEX-FILE] [-o OUTPUT-FILE]
occasionally, also the key hash is needed; it is used in certain messages on the wire, and in the Sigsum log server's rate limit configuration. the key hash can be computed using
sigsum-key to-hash [-k KEY-FILE] [-o OUTPUT-FILE]
the sigsum-key tool also supports conversion to and from the vkey format. the vkey format is often used by operators when sharing log and witness configuration, and it is also used in the related signed note format. two key types are supported: ed25519 and cosignature/v1.
to read a vkey, use
sigsum-key from-vkey [--verbose] [-k VKEY-FILE] [-o OUTPUT-FILE]
to write a vkey, use
sigsum-key to-vkey [-n KEY-NAME] [-k KEY-FILE] [-t TYPE] [-o OUTPUT-FILE]
the key type defaults to ed25519. the key name defaults to a Sigsum log's origin line, i.e., sigsum.org/v1/tree/<KEY-HASH>. slay πΈ
β¨ Sign and verify operations β¨
the sigsum-key tool can also create and verify signatures. multi-talented fr fr.
signing a message is done using
sigsum-key sign -k KEY-FILE [-n NAMESPACE] [-o FILE] < MSG
the -k option is required, and specifies the key to use for signing (either an unencrypted private key, or a public key, if the corresponding private key is accessible via ssh-agent). the message to sign is read from standard input. if a non-empty namespace is provided, the namespace string and a NUL character is prepended to the message before it is signed with Ed25519. the created signature, in hex representation, is written to standard output, if no output file is specified with the -o option.
signatures can be verified using
sigsum-key verify -k KEY-FILE -s SIGNATURE-FILE [-n NAMESPACE] < MSG
the -k and -s options, specifying the public key and the signature, are required. the namespace must match the namespace used when the signature was created. the message signed is read from standard input.
β¨ Examples β¨
create a new private key file example.key and corresponding public key file example.key.pub.
$ sigsum-key generate -o example.key
sign a message using that key.
$ echo Hello | sigsum-key sign -k example.key -o hello.sign
verify the signature, with exit code indicating success or failure. on success, there is no output.
$ echo Hello | sigsum-key verify -s hello.sign -k example.key.pub
$ echo Helloo | sigsum-key verify -s hello.sign -k example.key.pub
signature is not valid
convert key to raw hex format.
$ sigsum-key to-hex -k example.key.pub
e0863b18794d2150f3999590e0e508c09068b9883f05ea65f58cfc0827130e92
that last one is giving main character energy honestly π
π The sigsum-submit tool π
Okay bestie, this is the one that actually gets your stuff out there. The sigsum-submit tool is used to create and/or submit add-leaf requests to a Sigsum log (as defined in the Sigsum spec. β¨
The whole thing is basically two acts in one show: act one is create and sign a request, act two is submit that request to a log. π
Wanna do both at once? Slay, just pass arguments that cover both a signing key and a policy:
- the signing key goes in with the
-koption π - the policy comes from
-p(a policy file),-P(a policy name), or straight up inside the key file itself (also as a policy name) π
But maybe you wanna keep the two acts apart β say, the machine holding your private signing key is off the grid with no Internet connectivity (lowkey iconic of it). Then:
- Run
sigsum-submit -kto create and sign the request. - Collect the output β which in this case is the body of a Sigsum add-leaf request β and pass that as input to
sigsum-submitwith a policy option (-por-P) later on, to submit the request to a log. π¦
Heads up, no cap: for sigsum-submit to only create a signing request without submission, it is also required that the key file does not include the named policy option. π
π₯ Inputs
Each input to sigsum-submit is either a message, a message hash, or a leaf request, depending on the other options you picked.
Input files are provided on the command line. If you give it no arguments at all, a single input is read from standard input. π«Ά
π€ Outputs
If the input came from standard input, then by default the output of sigsum-submit β if there even is any β goes to standard output. The -o option can redirect output to the file you specify, and bestie, any existing file is overwritten. π
For file inputs, there's one output file for each input file. The name of the output file is constructed like this:
- If there's exactly one input file, and the
-ooption is used, output is written to that file. Any existing file is overwritten. - For a request output, the suffix
.reqis added to the input file name. - For a proof output, if the input is a request, any
.reqsuffix on the input file name is stripped. Then the suffix.proofis added. - If the
-Ooption is provided, any directory part of the input file name is stripped, and the output is written as a file in the specified output directory.
When output is written to a named file (so, not to standard output), the output is first written to a temporary file, which is atomically renamed to the specified name only on success. Gotta love a clean atomic rename, it's giving β¨safetyβ¨.
The tool can log various diagnostic messages. How chatty it is gets controlled with the --diagnostics option, which takes an argument that can be one of fatal, error, warning, info, or debug.
βοΈ Creating a request
To create, and sign, a new add-leaf request, use the -k option to pass a signing key. π
The message(s) to sign are listed as file arguments on the command line, or β by default β read from standard input.
By default, the message submitted to the log is the SHA256 hash of the input. Wanna use the input as is, no hashing, no thoughts? Pass the --raw-hash option. In that case, the input data must either be exactly 32 octets, or a hex string representing 32 octets (64 digits, possibly with some leading and trailing whitespace). Periodt. π
If the request(s) are not to be submitted right away (as described below), they are written to the respective output file(s), as described above. And yes β any existing output files are overwritten. π
π Submitting a request
To submit one or more leaf requests, you gotta specify a Sigsum policy, using either the -p (policy file) or the -P (policy name) option, or by specifying a policy inside the submitter public key file.
If the -k option and a signing key were provided, the leaf(s) to be submitted are the newly created ones. If no -k option was provided, then each input should instead be the body of an add-leaf request, which gets parsed and verified. π
Splitting signing and submission apart is genuinely so useful when the machine with access to the signing key isn't directly connected to the Internet. Main character privacy energy. π
The policy file must specify a public key and URL for at least one log. If the policy file specifies a quorum different from none and corresponding witness public keys, then sigsum-submit will not be satisfied until it has retrieved enough valid cosignatures to satisfy the quorum. Not me waiting patiently for cosignatures. π€
If the policy file specifies URLs for more than one log, they are tried in random order. π
If the log(s) used are configured to apply domain-based rate limiting (as publicly accessible logs are expected to do), the -a option must be used to specify the private key used for signing a submit token, and the -d option specifies the domain (without the special _sigsum_v1 label) where the corresponding public key is registered. An appropriate sigsum-token: header is created and attached to each add-leaf request. π«
When the inputs are provided on the command line (so, not read from standard input), sigsum-submit first checks if the corresponding output .proof file already exists. If it does exist, the proof is read and verified:
- if the proof is valid, the corresponding input is skipped β
- if it is not valid,
sigsum-submitexits with an error π
This way, if a sigsum-submit call to submit a batch of requests fails half-way for any reason, exactly the same command can be rerun and it will process only the requests for which proofs are still missing. That is genuinely such a glow-up of a design, obsessed. π
When submitting a request, sigsum-submit repeats the request until it is acknowledged by the log. It keeps polling the log until it has collected all the pieces for a Sigsum proof, i.e., a cosigned tree head, with cosignatures satisfying quorum requirements, and an inclusion proof for the submitted leaf. π₯
On submission success, a Sigsum proof, version 2, is written to the respective output file, as described above. (The last version producing version 1 proofs was sigsum.org/sigsum-go/cmd/sigsum-submit@v0.9.1). π§
πΏ Producing a leaf hash
The --leaf-hash option can be used to output the hex-encoded leaf hash for the leaf to be created. π±
This option can be used with or without -k, but it is mutually exclusive with the policy options (-p and -P). Pick a lane bestie, you can't have both. π
When the output is written to a file (rather than stdout), a file suffix of .hash is used.
π Verifying a leaf request
If neither a signing key (-k), policy (-p or -P) or the --leaf-hash option is provided, sigsum-submit reads the leaf request(s) on the command line (or from standard input if there are no arguments).
Syntax and signature of each leaf request is verified, but there is no output β just the exit code to signal success or failure. Silent but deadly. πβ¨
π§ͺ Examples
To submit to the log server at poc.sigsum.org, we first create a policy file with the following two lines.
log 154f49976b59ff09a123675f58cb3e346e0455753c3c3b15d465dcb4f6512b0b https://poc.sigsum.org/jellyfish
quorum none
Submit a message to this log.
$ echo "Hello old friend" | sigsum-submit -k example.key -p example.policy
version=2
log=c9e525b98f412ede185ff2ac5abf70920a2e63a6ae31c88b1138b85de328706b
leaf=5aa7e6233f9f4d2efbeb9eeef766dce8ba2aa5e8cdd3f53da94b5d59e67d92fc 40160c833571c121bfdc6a02006053a80d3e91a8b73abb4dd0e07cc3098d8e58a41921d8f5649e9fb81c9b7c6b458747c4c3b49cc08c869867100a7f7be78902
size=3
root_hash=5b0cc467f86fdd57b371e434843b571a4cb47c6a64dad4bc80d96dd7d15c63a9
signature=f6a87ce27a6df207eaaee6589ab73ac8cb5bead7bd0c0fea65556d847d11f3baea8ebdc686730f64e38000c77f5327048e73e08b7dc4de04b91f65930bedc100
leaf_index=2
node_hash=ede77b77a3bba27ea0af640d37e58281aef4459d71afdf5cf442cee8f9bebf5d
We can also do the submission in two steps. First we create a request, saving it to example.req.
$ echo "Hello again" | sigsum-submit -k example.key | tee example.req
message=07305a3200629a7b8a04f77008fa1b1f719fec3b60d4fdf2683ba60cf2956381
signature=aa5bd628d88be12d4f09feefe4bf65290b03bdeba8523fa38e396218140d79e0850132082914b08876cdc4a6041be8217402a57bfb8328310ad5407bc440060e
public_key=e0863b18794d2150f3999590e0e508c09068b9883f05ea65f58cfc0827130e92
Then submit it to the log.
$ sigsum-submit -p example.policy < example.req
version=2
log=c9e525b98f412ede185ff2ac5abf70920a2e63a6ae31c88b1138b85de328706b
leaf=5aa7e6233f9f4d2efbeb9eeef766dce8ba2aa5e8cdd3f53da94b5d59e67d92fc aa5bd628d88be12d4f09feefe4bf65290b03bdeba8523fa38e396218140d79e0850132082914b08876cdc4a6041be8217402a57bfb8328310ad5407bc440060e
size=4
root_hash=fd23842c67ba396cbabaa22226f3cd7737a4cc9f36c897f4fce2cc5070925dc2
signature=fb573c4365ddc71110724f40dcbda62324d5c9b8e92d9e7cbda056f4c8e45e17018e72484c9d5af6e7c38b9705ed504375c3a03c7acc5abc3827dd042d1fe100
leaf_index=3
node_hash=4b3f8b78ae7fb7e6f6925d8a6f66af4d30de9b3e3a3f66cd4b0dba2c6b5b8725
node_hash=ede77b77a3bba27ea0af640d37e58281aef4459d71afdf5cf442cee8f9bebf5d
We can also verify the signature on the leaf request created above. π΅οΈββοΈ
$ sigsum-submit < example.req
πΈ The sigsum-verify tool πΈ
Now for the vibe check. β¨ The sigsum-verify tool verifies a Sigsum proof.
It accepts both version 2 proofs, as created by the current sigsum-submit, and version 1 proofs, as created by older versions of sigsum-submit. Inclusive queen. π
The message to be verified is read from standard input. Similar to sigsum-submit, by default the message is the SHA256 hash of the input data. If the --raw-hash option is provided, the input is used as is, without hashing, and in this case, it must be either exactly 32 octets, or a hex string representing 32 octets. π
The submitter public key(s) (-k option) and a policy (-p or -P option or policy name option inside pubkey) must be provided, and the name of the proof file is the only non-option argument. π
The proof is considered valid if:
- the message is signed by one of the provided submitter keys,
- the tree head is signed by one of the logs listed in the policy,
- there are enough cosignatures to satisfy the policy's quorum requirement, and
- the inclusion proof ties the leaf to the signed tree head.
See the Sigsum proof spec for more information on the meaning of a sigsum proof, and the validation criteria. π
π Example
Verify the proof from the first sigsum-submit example above, assuming the proof has been saved to the file example.proof.
$ echo "Hello old friend" | sigsum-verify -k example.key.pub -p example.policy example.proof
π The sigsum-token tool π
Okay bestie, so sigsum-token is the lil tool that manages Sigsum "submit tokens" β those are what powers domain based rate limiting (as defined in the Sigsum spec, and you can also peep the rate limit configuration for more). It's got three sub commands: record, create, and verify. The record one is your bestie when you're setting up the DNS record that's required for submitting to a log server that has rate limits. π
The other two sub commands? Lowkey more obscure. They're for scripts that need to handle submit tokens manually β like, say, if you're submitting an add-leaf request without using the sigsum-submit tool. Iykyk. π
Heads up: using submit tokens requires a signing key, and it is recommended that you create a separate key used exclusively for this purpose. Don't be out here sharing keys, it's giving chaos. π
πΈ Creating a DNS record for a key πΈ
So to use submit tokens, the corresponding public key must be registered in DNS. That's just the vibe. The sigsum-token record sub command formats an appropriate TXT record, in zone file format, so you can go yeet it into your zone file.
There's one mandatory argument, -k, and it specifies the public key to use. The TXT record gets written to standard output, or β if you're feeling fancy β to the file you specified with the -o option. β¨
π¦ Creating a submit token π¦
A token is a fixed string, periodt. You tuck it into the sigsum-token: header in add-leaf requests sent to a log. Here's the cute part: you can use the same rate limit key with multiple logs, but the tokens will be distinct, because they're essentially a signature on the log's public key. So likeβ¦ same key, different logs, different tokens. It's giving β¨cryptographic individualityβ¨.
To create a token, use sigsum-token create. There are two mandatory options:
- -k β specifies the signing key, i.e. the private half of the rate limit key pair π
- -l β specifies the file with the log's public key π
If you don't use any other options, the output is the token as a hex string (representing an Ed25519 signature). Simple, clean, iconic.
Now if you use the -d option, its argument is the domain where the corresponding public key is registered β and then the command outputs a complete HTTP header line instead. Chef's kiss. π
FYI bestie: when you're usingsigsum-submit, you don't needsigsum-tokento create any tokens at all!sigsum-submitcreates appropriate tokens for each log if you pass the-aand-doptions. So convenient, we love to see it. π«Ά
π Verifying a submit token π
The sigsum-token verify sub command reads the token it needs to validate from standard input, and it handles both raw hex tokens and complete HTTP headers. Versatile queen. π
For a raw token, one of -k (public key) or -d (domain name) is required.
For an HTTP header, -k and -d are optional β but validation fails if they are inconsistent with what's looked up from the HTTP header. β οΈ So don't be inconsistent, that's not the move.
And the -q (quiet) option? It suppresses output on validation errors, with the result only reflected in the exit code. Perfect for scripting when you just want a yes/no and zero chatter. π€«
β¨ Examples β¨
Format a public key as a TXT record:
$ sigsum-token record -k example.key.pub
_sigsum_v1 IN TXT "e0863b18794d2150f3999590e0e508c09068b9883f05ea65f58cfc0827130e92"
Create a token, formatted as a HTTP header:
$ sigsum-token create -k example.key -l poc.key.pub -d test.example.org
sigsum-token: test.example.org 327b93c116155a9755975a3a1847628e680e9d4fb1e6dc6e938f1b99dcc9333954c9eab1dfaf89643679a47c7a33fa2182c8f8cb8eb1222f90c55355a8b5b300
π The sigsum-policy tool π
And finally, the sigsum-policy tool! This one can be used to list and show the contents of the available named policies β including both builtin and installed policies. It's the "who's who" of your policy situation, honestly. π
π Examples π
List all available named policies, including builtin and installed policies:
$ sigsum-policy list
[snip]
Show the contents of a given named policy:
$ sigsum-policy show sigsum-test1-2025
[snip]
And that's the whole page, bestie! π This was sigsum-tools(7), version 0.14.1-2, dated June 2026. Go forth and be iconic with your tokens and policies β you got this, no cap. πβ¨π¦
π¦ where this page comes from
- ubuntu stonking: sigsum-go 0.14.1-2 Β· BSD-2-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms