VOA(5)

πŸ“¦ version 0.7.6, in arch rolling

okay bestie, welcome to VOA(5) β€” File Formats Manual, section (5) β€” the page all about voa, the configuration file format for VOA technology backends. πŸ’…

✨ NAME ✨

voa β€” Configuration file format for VOA technology backends. periodt. πŸŽ€

πŸ¦‹ DESCRIPTION πŸ¦‹

so voa(5) is a YAML configuration file β€” yes, YAML, the format we all have a lil relationship with 😭 β€” and it encodes the OS-level and/or context-level settings for technology backends used in the File Hierarchy for the Verification of OS Artifacts (VOA[1]). iconic.

Each configuration file tracks a VOA OS identifier right there in its file name. like, arch.yaml is for the arch OS, and debian:13.yaml is for the debian:13 OS β€” head to the VOA specification for the full deets on the allowed character set. 🫢

and bestie, each configuration file must be a regular file to be considered. no cap. regular file or it literally does not count. πŸ’€

πŸ“ Directories and precedence πŸ“

The way config files get handled is based on the Configuration Files Specification[2]. iykyk.

For system users, voa files are read from these spots: the system VOA directories, the volatile runtime directory, and the local administration directory. specifically:

  • /usr/share/voa/ β€” system VOA directory
  • /usr/local/share/voa/ β€” system VOA directory
  • /run/voa/ β€” volatile runtime directory
  • /etc/voa/ β€” local administration directory

For real users, in addition to the system-wide configuration directories, voa files are also read from the voa/ directories in $XDG_CONFIG_DIRS and from the voa/ directory in $XDG_CONFIG_HOME (see XDG Base Directory Specification[3]). yes bestie, extra layers. 🧚

The order of the aforementioned directories describes the order of precedence in increasing priority. so a file from a directory with higher priority fully replaces one from a directory with lower priority β€” like, /etc/voa/example.yaml replaces /usr/share/voa/example.yaml, and ~/.config/voa/example.yaml replaces /etc/voa/example.yaml. she ate and left no crumbs. πŸ”₯

The voa configuration file format can also be used in drop-in configuration files. A drop-in is created for a specific OS by adding a voa configuration file in an override directory in one of the configuration directories. example: /etc/voa/example.yaml.d/99-custom-repo.yaml providing settings for a custom repository on the example OS, which overrides the more generic technology settings of the OS in /usr/share/voa/example.yaml. main character drop-in energy. πŸ‘‘

Note that drop-in configurations are read in lexicographic order, based on their file name, regardless of the directory precedence of their location. not me alphabetizing my override sitch β€” but yes, lexicographic, periodt.

Each voa configuration file can be masked by creating a symlink to /dev/null in its place. so like, /etc/voa/example.yaml -> /dev/null will cause the file /usr/share/voa/example.yaml to not be considered. poof, gone, masked. πŸ™ˆ

🧚 Merging of built-in defaults, OS and context-level settings 🧚

When deriving OS or context-level technology settings from voa configuration files, built-in defaults may be considered. so yes, the defaults can come to the function. ✨

After reading all configuration and drop-in configuration files, the available OS-level technology settings are constructed from them, with unset fields populated using already existing OS-level settings, or built-in defaults. it's giving layered inheritance realness.

Eventually, the available context-level technology settings are constructed from the configuration and drop-in configuration files, with unset fields populated using β€” depending on availability β€” OS-level defaults, or built-in defaults. lowkey a whole cascade. 🌈

NOTE: The following merging logic applies β€” unless stated otherwise β€” for all optional fields in the configuration file objects: if an optional field is omitted or set to null, a concrete value for it is derived either from OS-level, or if not provided there either, built-in defaults. While this allows for rich override and inheritance logic, it also implies the necessity to be explicit where necessary! so like, be explicit bestie, don't make her guess. πŸ’…

If an OS is not covered by a specific configuration or drop-in configuration file, the built-in defaults apply. that's the safety net, and it's iconic. ⭐

πŸ“ FILE FORMAT πŸ“

Okay bestie, here's the vibe: no cap, the file has to contain valid YAML data, and every single required field and value described below has to be present. Invalid voa files? Literally ignored. Periodt. πŸ’…


πŸ’– default_technology_settings object πŸ’–

The top-level object in the file which contains option objects for each available technology backend used in VOA. This one is giving top-level main character energy. πŸ‘‘

WARNING: Not me having to warn you, but for the voa file as a whole to be considered valid, this object must be defined, if the contexts list is empty! 🚨 fr fr

πŸ”₯ openpgp object πŸ”₯

The object describes the settings for the OpenPGP backend. Verification is based on OpenPGP signatures[4] and OpenPGP certificates[5]. Several verification methods are available. Slay. ✨

🧚 num_data_signatures number 🧚

The optional number of OpenPGP signatures from individual issuing OpenPGP certificates required for an artifact to be considered verified.

If set, the value must be a non-zero, positive integer (built-in default: 1).

🌸 verification_method object 🌸

The method used to verify OpenPGP signatures using OpenPGP certificates. The value must be one of the following objects. iykyk.

πŸŽ€ plain verification method object πŸŽ€

The plain verification method for OpenPGP signatures is a basic form of verification, that only considers artifact verifiers but no trust anchors. With it, one or more of the found artifact verifiers for a verification query must be used to successfully verify one or more OpenPGP signatures.

To constrain the set of OpenPGP certificates allowed as artifact verifiers, it can be filtered by domain name matches against valid OpenPGP User IDs[6] and/or OpenPGP fingerprint[7]. If no filters are defined, all OpenPGP certificates found in an artifact verifier location of a given context are considered as artifact verifiers.

πŸ¦‹ identity_domain_matches set πŸ¦‹

An optional set of valid domain names, that is used to filter artifact verifiers.

If the set has entries, a valid OpenPGP certificate found in the artifact verifier location of a given context is only considered if one of its valid OpenPGP User IDs matches one of the domain names.

If the set is empty (the built-in default), no filtering based on domain names occurs and any valid OpenPGP certificate found in the artifact verifier location of a given context is considered (assuming no other filter prevents it).

πŸ’œ fingerprint_matches set πŸ’œ

An optional set of OpenPGP fingerprints, that is used to filter artifact verifiers.

WARNING: The number of entries in this set must be equal to or greater than the number of required data signatures (see num_data_signatures) for the verification method as a whole to be considered valid! 😭

If the set has entries, a valid OpenPGP certificate found in the artifact verifier location of a given context is only considered if its OpenPGP fingerprint matches one of the fingerprints from the set.

If the set is empty (the built-in default), no filtering based on fingerprints occurs and any valid OpenPGP certificate found in the artifact verifier location of a given context is considered (assuming no other filter prevents it).

πŸ‘‘ trust_anchor verification method object πŸ‘‘

The trust anchor verification method for OpenPGP signatures is a basic form of trust anchor based verification, that considers both artifact verifiers and trust anchors when verifying a signature. With it, each artifact verifier must be certified by a specific number of the available trust anchors to be considered for the verification of OpenPGP signatures.

To constrain the set of valid OpenPGP certificates allowed as artifact verifier, it can be filtered by domain name matches against valid OpenPGP User IDs. To constrain the set of valid OpenPGP certificates allowed as trust anchor, it can be filtered by OpenPGP fingerprints.

🫢 required_certifications number 🫢

The optional number of OpenPGP third-party certifications[8] of trust anchors on artifact verifiers for an artifact verifier to be considered fully trusted. If set, the value must be a non-zero, positive integer (built-in default: 3). This one is highkey important. 🫢

🌈 artifact_verifier_identity_domain_matches set 🌈

An optional set of valid domain names, that is used to filter artifact verifiers.

If the set has entries, a valid OpenPGP certificate found in the artifact verifier location of a given context is only considered if one of its valid OpenPGP User IDs matches one of the domain names from the set and it has the required amount of OpenPGP third-party certifications from valid trust anchors.

If the set is empty (the built-in default), no filtering based on domain names occurs and any valid OpenPGP certificate found in the artifact verifier location which has at least one OpenPGP User ID with the required amount of OpenPGP third-party certifications from valid trust anchors is considered.

⭐ trust_anchor_fingerprint_matches set ⭐

An optional set of OpenPGP fingerprints, that is used to filter trust anchors.

WARNING: The number of entries in this set must be equal to or greater than the number of required certifications (see required_certifications) for the verification method as a whole to be considered valid! πŸ’€

If the set has entries, a valid OpenPGP certificate found in the trust anchor location of a given context is only considered if its OpenPGP fingerprint matches one of the fingerprints from the set.

If the set is empty (the built-in default), no filtering based on fingerprints occurs and any valid OpenPGP certificate found in the trust anchor location of a given context is considered.

πŸ•ΈοΈ web_of_trust verification method object πŸ•ΈοΈ

The Web of Trust[9] verification method for OpenPGP signatures is a flexible form of trust based verification, which relies on the Berblom algorithm[10]. It considers both artifact verifiers and trust anchors. With it, each artifact verifier must reach a configurable amount of trust to be considered for the verification of OpenPGP signatures. Here, the trust amount is calculated by a Web of Trust network, which relies on implicit or explicit trust roots and configurable trust amounts for partially trusted introducers in the network.

To constrain the set of valid OpenPGP certificates allowed as artifact verifier, it can be filtered by domain name matches against valid OpenPGP User IDs. To constrain the set of valid OpenPGP certificates allowed as trust anchor, it can be filtered by OpenPGP fingerprints.

🌟 flow_amount number 🌟

The optional trust amount required for a flow in a Web of Trust network to be considered fully trusted. This signifies the target trust amount that an artifact verifier must reach for it to be considered for the verification of OpenPGP signatures.

If set, the value must be a non-zero, positive integer (built-in default: 120).

πŸ“ partial_amount number πŸ“

The optional trust amount for a partially trusted introducer in a Web of Trust network. This signifies the trust amount of an OpenPGP certificate considered on a path between trust anchor and artifact verifier.

If set, the value must be an integer between 1 and 120 (built-in default: 40).

🎁 roots set of objects 🎁

A set of trust roots for the Web of Trust. Each object in this set signifies an OpenPGP certificate that is considered as trust root, alongside its specific trust amount.

Each trust root is an object with the following two fields:

  • fingerprint β€” An OpenPGP fingerprint.
  • amount β€” The optional trust amount assigned to the trust root. If set, the value must be an integer between 1 and 120 (built-in default: 120).
NOTE: If this field is omitted, a concrete value is derived from built-in defaults. 🫢

If the set has entries, a valid OpenPGP certificate found in the trust anchor location of the VOA hierarchy for a given context is considered as trust root with the specific trust amount if its OpenPGP fingerprint matches that of a fingerprint in the set.

If the set is empty, any valid OpenPGP certificate found in the trust anchor location of the VOA hierarchy for a given context is considered as trust root with a trust amount of 120.

🧸 artifact_verifier_identity_domain_matches set 🧸

An optional set of valid domain names, that is used to filter artifact verifiers.

If the set has entries, a valid OpenPGP certificate found in the artifact verifier location of a given context is only considered if one of its valid OpenPGP User IDs matches one of the domain names from the set and it has the required target trust amount (see flow_amount).

If the set is empty, no filtering based on domain names occurs and any valid OpenPGP certificate found in the artifact verifier location which has at least one OpenPGP User ID with the required target trust amount (see flow_amount) is considered.

πŸ—‚οΈ contexts list of objects πŸ—‚οΈ

A list of zero or more objects, that each provide a context-level override to the technology settings imposed by the OS (if any) or the built-in defaults.

WARNING: For the voa file as a whole to be considered valid, the default_technology_settings object must be defined, if this list is empty or the field is not set! 🚨

🎯 purpose string 🎯

The VOA purpose of the OS, that is targeted. Refer to the VOA specification for details on the allowed character set.

🧭 context string 🧭

The VOA context of the OS, that is targeted. Refer to the VOA specification for details on the allowed character set.

βš™οΈ technology_settings object βš™οΈ

Technology settings for the purpose and context of the OS targeted by the configuration file name (or drop-in directory name).

The settings in this object override the less specific OS-level or built-in technology settings. Refer to the default_technology_settings section for an overview of the expected object.

πŸ’– EXAMPLES πŸ’–

πŸŽ€ Defaults πŸŽ€

Okay so here’s the built-in defaults for technology settings, bestie β€” this is the out-of-the-box vibe:

default_technology_settings:
  openpgp:
    num_data_signatures: 1
    verification_method:
      trust_anchor:
        required_certifications: 3
        artifact_verifier_identity_domain_matches:
        trust_anchor_fingerprint_matches:

This config is targeting the basic β€œtrust anchor” method for OpenPGP. It requires a single data signature for artifacts and at least three certifications on artifact verifiers from trust anchors.

The set of domain name matches for artifact verifiers and OpenPGP fingerprint matches for trust anchors are left empty on purpose β€” that means no specific restrictions on those verifiers are imposed. Slay. ✨

πŸ¦‹ OpenPGP β€œplain” verification method πŸ¦‹

This next configuration example targets the β€œplain” verification method for OpenPGP:

default_technology_settings:
  openpgp:
    num_data_signatures: 1
    verification_method:
      plain:
        identity_domain_matches:
          - example.org
          - sub.example.org
        fingerprint_matches:
          - d3b0f7c0b825ecbb0f0d7398072947e7b1537b6f
          - e242ed3bffccdf271b7fbaf34ed72d089537b42f
          - f1d2d2f924e986ac86fdf7b36c94bcdf32beec15

Assuming those contents live in the file /usr/share/voa/example.yaml, for the OS example the following verification rules apply:

A single data signature from a valid artifact verifier is required for artifacts to be verified. Further, these restrictions are imposed on OpenPGP certificates found in the artifact verifier location of a specific context to be considered valid:

  • A valid OpenPGP User ID must match either the domain example.org or sub.example.org.
  • The OpenPGP fingerprint must match d3b0f7c0b825ecbb0f0d7398072947e7b1537b6f, e242ed3bffccdf271b7fbaf34ed72d089537b42f, or f1d2d2f924e986ac86fdf7b36c94bcdf32beec15.

🌸 OpenPGP basic β€œtrust anchor” verification method 🌸

This one targets the basic β€œtrust anchor” verification method for OpenPGP:

default_technology_settings:
  openpgp:
    num_data_signatures: 1
    verification_method:
      trust_anchor:
        required_certifications: 3
        artifact_verifier_identity_domain_matches:
          - example.org
          - sub.example.org
        trust_anchor_fingerprint_matches:
          - d3b0f7c0b825ecbb0f0d7398072947e7b1537b6f
          - e242ed3bffccdf271b7fbaf34ed72d089537b42f
          - f1d2d2f924e986ac86fdf7b36c94bcdf32beec15

Assuming those contents are in /usr/share/voa/example.yaml, for the OS example the following verification rules apply:

A single data signature from a valid artifact verifier is required for artifacts to be verified. Each artifact verifier must be certified by three trust anchors.

A valid OpenPGP User ID of a valid OpenPGP certificate found in the artifact verifier location of a specific context must match either the domain example.org or sub.example.org for the certificate to be considered as artifact verifier.

The OpenPGP fingerprint of a valid OpenPGP certificate found in the trust anchor location of a specific context must match either d3b0f7c0b825ecbb0f0d7398072947e7b1537b6f, e242ed3bffccdf271b7fbaf34ed72d089537b42f, or f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 for the certificate to be considered as trust anchor. πŸ’…

πŸ”₯ OpenPGP β€œWeb of Trust” verification method πŸ”₯

This configuration example targets the β€œWeb of Trust” verification method for OpenPGP:

default_technology_settings:
  openpgp:
    num_data_signatures: 1
    verification_method:
      web_of_trust:
        flow_amount: 120
        partial_amount: 40
        roots:
          - fingerprint: d3b0f7c0b825ecbb0f0d7398072947e7b1537b6f
            amount: 120
          - fingerprint: e242ed3bffccdf271b7fbaf34ed72d089537b42f
            amount: 120
          - fingerprint: f1d2d2f924e986ac86fdf7b36c94bcdf32beec15
            amount: 120
        artifact_verifier_identity_domain_matches:
          - example.org
          - sub.example.org

Assuming those contents are in /usr/share/voa/example.yaml, for the OS example the following verification rules apply:

A single data signature from a valid artifact verifier is required for artifacts to be verified.

Each partially trusted introducer in the β€œWeb of Trust” network is assigned a trust amount of 40. The trust amount required for a valid OpenPGP certificate found in the artifact verifier location of a given context to be considered β€œfully trusted” β€” and therefore considered as artifact verifier β€” is 120.

The OpenPGP fingerprint of a valid OpenPGP certificate found in the trust anchor location of a specific context must match either d3b0f7c0b825ecbb0f0d7398072947e7b1537b6f, e242ed3bffccdf271b7fbaf34ed72d089537b42f, or f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 for the certificate to be considered as trust anchor. Each of these matching trust anchors is assigned a trust amount of 120. Iconic. πŸ‘‘

⭐ OS-level and context-level ⭐

Here’s an example of OS and context-level technology settings relying on the basic β€œtrust anchor” verification method for OpenPGP. It’s assumed the contents live in /usr/share/voa/example.yaml, so it’s targeting the OS example.

default_technology_settings:
  openpgp:
    num_data_signatures: 2
    verification_method:
      trust_anchor:
        artifact_verifier_identity_domain_matches:
          - example.org
        trust_anchor_fingerprint_matches:
          - 6132b58967cf1ebc05062492c17145e5ee9f82a8
          - 6eadeac2dade6347e87c0d24fd455feffa7069f0
          - b787a81c32997fd39a5f4c0188363902d3586e7b
          - d3b0f7c0b825ecbb0f0d7398072947e7b1537b6f
          - e242ed3bffccdf271b7fbaf34ed72d089537b42f
contexts:
  - purpose: package
    context: default
    technology_settings:
      openpgp:
        verification_method:
          trust_anchor:
            required_certifications: 4
            artifact_verifier_identity_domain_matches:
              - packages.example.org
  - purpose: image
    context: installation-medium
    technology_settings:
      openpgp:
        num_data_signatures: 1
        verification_method:
          trust_anchor:
            artifact_verifier_identity_domain_matches:
              - install.example.org

If a system using this configuration file does not have any other voa file, the built-in defaults apply for any unset fields in the OS-level technology settings, and the OS-level technology settings apply for any unset fields in the context-level technology settings.

The above example shows how OS-level defaults are handed down if they’re not set in the more specific context-level settings. For example, the trust_anchor_fingerprint_matches in the OS-level defaults also apply to the context-level technology settings.

Relatedly, fields in context-level technology settings can override OS-level defaults. In the above example, the num_data_signatures are set to 2 on the OS level, but one of the contexts overrides it to require only 1. Similarly, the required_certifications in one of the contexts is overridden to 4 instead of the OS-level value of 3 β€” which is itself derived from the built-in defaults. So extra, so valid. πŸ’–

🧚 Drop-ins for context-level overrides 🧚

When you’re only providing context-level settings, the top-level default_technology_settings key can be omitted.

The following configuration example targets the β€œplain” verification method for OpenPGP. It’s assumed the contents live in /etc/voa/example.yaml.d/90-my-repo.yaml, targeting the OS example.

contexts:
  - purpose: package
    context: my-repo
    technology_settings:
      openpgp:
        num_data_signatures: 1
        verification_method:
          plain:
            identity_domain_matches:
              - other.org
            fingerprint_matches:
              - bea43e7033e19327183416f23fe2ee1b64c25f4a

Assuming the configuration described in the OS-level and context-level example is also present on the system, this configuration describes a specialization for a single package repository named my-repo. Technology settings enforced by the OS example are overridden, and a different set of verification rules apply:

  • Only one data signature from valid artifact verifiers is required for each artifact.
  • The following restrictions are imposed by filters on the verifiers:
    • Valid OpenPGP certificates found in relevant locations are only considered as artifact verifiers if their OpenPGP fingerprint matches bea43e7033e19327183416f23fe2ee1b64c25f4a.
    • Valid OpenPGP certificates found in relevant locations are only considered as artifact verifiers if one of their valid OpenPGP User IDs matches the domain name other.org.

🌈 SEE ALSO 🌈

voa(1)

πŸ¦‹ NOTES πŸ¦‹

  1. VOA

https://uapi-group.org/specifications/specs/file_hierarchy_for_the_verification_of_os_artifacts/

  1. Configuration Files Specification

https://uapi-group.org/specifications/specs/configuration_files_specification/

  1. XDG Base Directory Specification

https://specifications.freedesktop.org/basedir/latest/

  1. OpenPGP signature

https://openpgp.dev/book/signatures.html

  1. OpenPGP certificate

https://openpgp.dev/book/certificates.html

  1. OpenPGP User ID

https://openpgp.dev/book/certificates.html#user-ids

  1. OpenPGP fingerprint

https://openpgp.dev/book/certificates.html#fingerprint

  1. OpenPGP third-party certifications

https://openpgp.dev/book/signing_components.html#third-party-certifications

  1. Web of Trust

https://codeberg.org/openpgp/wot

  1. Berblom algorithm

https://codeberg.org/Nukesor/berblom


Cute sign-off time, bestie: that’s the whole voa(5) page β€” manual section (5), with the footer’s source/version and date doing their official main-character thing at the bottom. Bye and slay! πŸ’…πŸ’–

πŸ“¦ where this page comes from