# VOA
A command line interface and library for interacting with the "File Hierarchy for the **V**erification of **O**S **A**rtifacts" ([VOA]).
## Documentation
- <https://voa.archlinux.page/rustdoc/voa/> for development version of the crate
- <https://docs.rs/voa/latest/voa/> for released versions of the crate
## Examples
### Library
```rust
use std::io::Write;
use tempfile::{NamedTempFile, tempdir};
use voa::commands::{load_verifier, write_verifier_to_hierarchy};
# fn main() -> testresult::TestResult {
// Write a generic OpenPGP certificate to a temporary file.
let cert = r#"-----BEGIN PGP PUBLIC KEY BLOCK-----
xjMEaNBDAhYJKwYBBAHaRw8BAQdAzjzrpQ/AEteCmzjd1xTdXGaHV0VKSm4HLy6l
HVcmWT3NH0pvaG4gRG9lIDxqb2huLmRvZUBleGFtcGxlLm9yZz7CmgQQFggAQgUC
aNBDAhYhBEauMg3lOimFWKbyoPtSEBy0DfYKAhsDAh4BBAsJCAcGFQ4KCQwIARYN
JwkCCAIHAgkBCAEHAQIZAQAKCRD7UhActA32CkhIAP9bhoLJeZRCAc+q1kFEkstT
uXBPlzHagF6ghuUfToMmVQD+KaakONKSekglKR4rJxzhleQJ4qsptt1gjXX13QgF
Xwo=
=Pkv9
-----END PGP PUBLIC KEY BLOCK-----"#;
let mut temp_file = NamedTempFile::new()?;
write!(temp_file, "{cert}")?;
let input_path = temp_file.path();
// Load OpenPGP verifier from file.
let verifier = load_verifier(Some(input_path.try_into()?), "openpgp".parse()?)?;
// Prepare a temporary output directory.
let temp_dir = tempdir()?;
// Write a verifier to a location in a temporary VOA hierarchy.
write_verifier_to_hierarchy(verifier, temp_dir, "os".parse()?, "packages".parse()?, None)?;
# Ok(())
# }
```
### CLI
The `voa` CLI offers a simple interface for dealing with data in a VOA hierarchy.
#### Import verifiers
Verifiers can be imported using the `voa import` subcommand.
Assuming that the environment variable `OPENPGP_CERT` contains the path to an [OpenPGP certificate] with [signing capabilities], we can import it to a VOA hierarchy directory (represented by the `VOA_DIR` environment variable).
The following imports the [OpenPGP certificate] to the directory `os/packages/openpgp/` in `VOA_DIR`, implying that this verifier is to be used for the verification of package files on the OS `os`.
```bash
rpgp show "$OPENPGP_CERT"
voa import os packages openpgp --input "$OPENPGP_CERT" --base-path "$VOA_DIR"
# 🔐 EdDSA/Curve25519 v4 f992bda338ded64fe062302b5bd40d64577b8ea2
# ⏱ Created 2025-09-20 06:13:33 UTC
#
# 🪪 ID "John Doe <john.doe@example.org>"
# 🖋 CertGeneric 2025-09-20 06:13:33 UTC, by 5bd40d64577b8ea2 [EdDSALegacy, SHA256, V4]
#
cd "$VOA_DIR" || exit
tree .
# .
# └── os
# └── packages
# └── default
# └── openpgp
# └── f992bda338ded64fe062302b5bd40d64577b8ea2.openpgp
rpgp show os/packages/default/openpgp/*.openpgp
# 🔐 EdDSA/Curve25519 v4 f992bda338ded64fe062302b5bd40d64577b8ea2
# ⏱ Created 2025-09-20 06:13:33 UTC
#
# 🪪 ID "John Doe <john.doe@example.org>"
# 🖋 CertGeneric 2025-09-20 06:13:33 UTC, by 5bd40d64577b8ea2 [EdDSALegacy, SHA256, V4]
#
```
## Contributing
Please refer to the [contribution guidelines] to learn how to contribute to this project.
## License
This project can be used under the terms of the [Apache-2.0] or [MIT].
Contributions to this project, unless noted otherwise, are automatically licensed under the terms of both of those licenses.
[Apache-2.0]: ../LICENSES/Apache-2.0.txt
[MIT]: ../LICENSES/MIT.txt
[OpenPGP certificate]: https://openpgp.dev/book/certificates.html
[VOA]: https://uapi-group.org/specifications/specs/file_hierarchy_for_the_verification_of_os_artifacts/
[contribution guidelines]: ../CONTRIBUTING.md
[signing capabilities]: https://openpgp.dev/book/certificates.html#defining-operational-capabilities-of-component-keys-with-key-flags