Named policies for Sigsum

Author: Elias Rudberg
Date: 2026-02-04


The Sigsum project just added support for a new feature called named policies. This blog post aims to explain why and how named policies have been introduced for Sigsum.

Sigsum

Sigsum is a free and open-source software project that provides specifications and tools to create a transparency log system. Apart from the transparency logs themselves, such a system is composed of cosigning witnesses, submitters who submit signed checksums to the logs, verifiers who consume proofs of logging, and monitors that can generate alerts. This ensures each signature made with a given key must be publicly logged, i.e., otherwise that signature would not be accepted by the verifiers. With the help of monitors, submitters can thus be notified of rogue signatures that verifiers would accept as valid and then start doing something about it (rather than simply not knowing about the rogue signatures).

The role of witnesses is to check that a log behaves as it should, meaning that the log is append-only. New log entries can be added, but existing log entries can never be changed or removed. A proof of logging includes cosignatures from witnesses. The idea is that cosignatures from multiple independent witnesses can make a proof more trustworthy. Each cosignature is essentially a sign-off that the log is append-only.

When Sigsum is used in practice, each verifier needs to know what criteria to use for deciding if a given proof of logging is valid. This information is referred to as a Sigsum policy, sometimes also called a Sigsum trust policy. A policy includes a set of public keys for logs and witnesses as well a quorum rule. The quorum rule essentially tells the verifier how many witness cosignatures are required for the proof to be valid. For example, a simple quorum rule would be to require sign-offs from three out of five witnesses.

The problem of communicating which policy to use

Someone (a submitter) who submits signed checksums to a Sigsum log typically specifies a policy to be used by the sigsum-submit tool, and will for each submission get a proof that can be verified using the given policy. If the submitter wants others to be able to verify the proofs, it is necessary to somehow communicate to others what policy the submitter thinks should be used.

As an example, the description of how to verify age v1.2.1 release signatures contains a policy that verifiers can copy and paste. It looks like this:

$ cat << EOF > sigsum-trust-policy.txt
log 154f49976b59ff09a123675f58cb3e346e0455753c3c3b15d465dcb4f6512b0b https://poc.sigsum.org/jellyfish
witness poc.sigsum.org/nisse 1c25f8a44c635457e2e391d1efbca7d4c2951a0aef06225a881e46b98962ac6c
witness rgdd.se/poc-witness  28c92a5a3a054d317c86fc2eeb6a7ab2054d6217100d0be67ded5b74323c5806
group  demo-quorum-rule all poc.sigsum.org/nisse rgdd.se/poc-witness
quorum demo-quorum-rule
EOF

Then the resulting sigsum-trust-policy.txt file can be given as input to the sigsum-verify tool:

$ sigsum-verify -k age-sigsum-key.pub -p sigsum-trust-policy.txt \
    age-v1.2.0-darwin-arm64.tar.gz.proof < age-v1.2.0-darwin-arm64.tar.gz

As another example, the release announcement for inetutils-2.6 includes instructions about how to fetch a policy file using wget. It looks like this:

$ wget -q -Otrust.txt https://gnu.org/s/inetutils/sigsum-policy.txt

Again, the resulting trust.txt file can be given as input to the sigsum-verify tool to verify the Sigsum proof for the release.

While communicating the policy to be used in ways like the above is possible, it is not without drawbacks. For example, it is cumbersome both for the submitter who needs to handle the extra complication of providing the policy file contents, and for users who have to use extra commands before they can verify the proof. There is also a risk that a user makes a mistake and ends up not using the right policy.

The work on named policies started with a simple question: can we do better?

Introducing named policies

The Sigsum tools sigsum-verify, sigsum-submit, and sigsum-monitor each expect the user to specify which policy to use. That can now be done either using the -p policy-file option (where policy-file is a file supplied by the user), or using the -P policy-name option, where policy-name is the named policy to use, which can be either a built-in policy or a policy installed as a file in the /etc/sigsum/policy/ directory.

Thus, there are two kinds of named policies: built-in policies and installed policies.

Built-in named policies are defined by the Sigsum project and distributed as part of the Sigsum tools. This has the advantage that those policies are available for anyone who uses the Sigsum tools, without need to install anything extra.

Installed named policies are any files placed in the /etc/sigsum/policy/ directory. This possibility can be useful when some other organization (not the Sigsum project) wants to distribute a Sigsum policy.

The sigsum-policy tool can be used to list available named policies (including both built-in and installed policies), and to show the contents of a given named policy. Example:

$ sigsum-policy list
sigsum-generic-2025-1
sigsum-test-2025-3
sigsum-test1-2025
sigsum-test2-2025

The output seen above means that there were four named policies available. Note that the set of available policies will depend on the version of the sigsum tools installed as well as any installed policies found in the /etc/sigsum/policy/ directory on the local system. The command sigsum-policy show can be used to show the contents of a given named policy:

$ sigsum-policy show sigsum-test1-2025
[INFO] Found builtin policy '"sigsum-test1-2025"'
# Policy using the sigsum test log at test.sigsum.org/barreleye

log 4644af2abd40f4895a003bca350f9d5912ab301a49c77f13e5b6d905c20a5fe6 https://test.sigsum.org/barreleye

witness poc.sigsum.org/nisse         1c25f8a44c635457e2e391d1efbca7d4c2951a0aef06225a881e46b98962ac6c
witness rgdd.se/poc-witness          28c92a5a3a054d317c86fc2eeb6a7ab2054d6217100d0be67ded5b74323c5806
witness witness1.smartit.nu/witness1 f4855a0f46e8a3e23bb40faf260ee57ab8a18249fa402f2ca2d28a60e1a3130e

# Requiring 2 of 3 is intended to give reasonable reliability.
group quorum-rule 2 poc.sigsum.org/nisse rgdd.se/poc-witness witness1.smartit.nu/witness1

quorum quorum-rule

For a more detailed description of how a policy can be specified, including the possibility of having a policy name inside a submitter public key file, see the Policies section in the Sigsum command line tools documentation. Examples showing how the tools sigsum-submit, sigsum-verify, and sigsum-monitor can be used with a named policy can be found in the Sigsum getting started guide.

Test policies

A few built-in test policies have been added, using logs and witnesses that are intended for test and development purposes only. The test policies are used in the same way as production policies, the only difference is that test policies have “test” in the policy name.

Production policies

The first built-in named policy published by the Sigsum project is “sigsum-generic-2025-1” which was included in version 0.13.0 of the Sigsum tools. It is the first in a sequence of sigsum-generic-* named policies. The idea is that when circumstances change in the future, in particular as more production logs and witnesses become available, new sigsum-generic-* policies will be added based on the procedure outlined in the policy maintenance document.

The “sigsum-generic-2025-1” policy uses two logs (operated by Glasklar Teknik and Mullvad VPN) and three witnesses (operated by Glasklar Teknik, Mullvad VPN, and Tillitis). One weakness of this policy is that even though the three witnesses are operated by separate companies, all three have the same parent company and so are dependent in some ways. Future sigsum-generic-* policies will likely improve upon this by adding witnesses that contribute with additional degrees of independence.

Changes over time

Once a built-in named policy has been released, its contents should not change. This ensures that if verification of a given sigsum proof passed once, it will continue to pass as long as the same policy name is used.

Since each released policy name should retain the same meaning, any changes over time should be done by releasing new policies rather than changing the existing ones. So instead of having different versions of the policy contents for a given policy name, each new version should get its own unique policy name. As an example, if new production witnesses become available during 2026 that allow creating a stronger policy, then a new policy named sigsum-generic-2026-1 can be added that includes new witnesses, while the existing policy sigsum-generic-2025-1 still has the same contents as before.

(Of course, it is technically possible that a policy name could change its meaning. One way that can happen is through changes in the source code defining the built-in policies; anyone who wishes to compile from source can modify the source code including the built-in policies. Another way it can happen is if the same policy name is used for both a built-in policy and for an installed policy, in which case the installed policy will be used.)

Example usage

As described earlier, the description of how to verify age v1.2.1 release signatures included policy file contents that users could copy and paste. In contrast, the corresponding description for age v1.3.1 is significantly simpler because it uses the sigsum-generic-2025-1 built-in named policy instead.

Comparing the two cases, in the first case (for age v1.2.1) there is first a preparatory step creating the policy file sigsum-trust-policy.txt and then the sigsum-verify command with the option -p sigsum-trust-policy.txt.

In the second case (for age v1.3.1) there is no need to create a policy file, instead the sigsum-verify command is used with the -P sigsum-generic-2025-1 option, where sigsum-generic-2025-1 is a built-in named policy:

$ sigsum-verify -k age-sigsum-key.pub -P sigsum-generic-2025-1 \
    age-v1.3.0-darwin-arm64.tar.gz.proof < age-v1.3.0-darwin-arm64.tar.gz

That’s it

Hopefully this blog post helped explain what the new named policy functionality is all about. Feel free to try it out yourself, and please reach out if you have any questions or comments about named policies!


Acknowledgment: Thanks to Rasmus Dahlberg for his help with this blog post.