# `omnibor`
__Reproducible identifiers & fine-grained build dependency tracking for software artifacts.__
[![Website](https://img.shields.io/badge/website-omnibor.io-blue)](https://omnibor.io) [![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/omnibor/omnibor-rs/blob/main/LICENSE)
This is a Rust implementation of the [OmniBOR] specification, which defines
a reproducible identifier scheme and a fine-grained build dependency tracking
mechanism for software artifacts.
The goal for OmniBOR is to be incorporated into software build tools, linkers,
and more, so software consumers can:
- Reproducibly identify software artifacts;
- Deeply inspect all the components used to construct a software artifact,
beyond just what packages are in a dependency tree;
- Detect when dependencies change through updated artifact identifiers.
The last point is key: Artifact ID's incorporate dependency information,
forming a variant of a Merkle Tree! This Directed Acyclic Graph (DAG) of
dependencies cascades up evidence of artifact dependency changes, enabling
consumers of software artifacts to know when changes happen, and what
precisely has changed.
> [!IMPORTANT]
> The OmniBOR spec, and this Rust package, are still a work-in-progress.
> This also means it's a great time to contribute!
>
> If you want to contribute to the specification instead, check out the
> [OmniBOR spec] repository.
## Using
### Using from Rust
Run the following to add the library to your own crate.
```sh
$ cargo add omnibor
```
The `omnibor` crate currently exposes the following features:
| Name | Description | Default? |
|:--------|:------------------------------------------------------------|:---------|
| `serde` | Add support for serializing and deserializing `ArtifactId`s | No |
To turn on a feature, you can run `cargo add omnibor --features=""`, or
[edit your `Cargo.toml` to activate the feature][features].
### Using from other languages
The `omnibor` crate is designed to also be used from other programming languages!
All API's in the crate are exposed over a Foreign Function Interface, usable by
anything that can consume C code.
The crate is configured to produce files suitable for either static or dynamic linking
with non-Rust code. Additionally, you'll need to use `cbindgen` to produce a header
file which describes the contents of the linkable library.
## Testing
`omnibor` provides a variety of tests, which can be run with `cargo test`. To ensure
serialization and deserialization code are tested as well, run
`cargo test --features="serde"`.
## Design
The OmniBOR Rust implementation is designed with the following goals in mind:
- __Cross-language readiness__: The OmniBOR Rust implementation should be
built with solid Foreign Function Interface (FFI) support, so it can be
used as the basis for libraries in other languages.
- __Multi-platform__: The OmniBOR Rust implementation should be ready for
use in as many contexts as possible, including embedded environments. This
means supporting use without an allocator to dynamically allocate memory,
and minimizing the size of any types resident in memory.
- __Fast__: The OmniBOR Rust implementation should run as quickly as possible,
and be designed for high-performance use cases like rapid large scale
matching of artifacts to identifiers.
- __Memory efficient__: The OmniBor data is designed to be of minimal size in
memory, with the understanding that real-world uses of `omnibor` are likely
to work with large number of identifiers at a time. For example, the type
`ArtifactId` is exactly 32 bytes, just the number of bytes necessary
to store the SHA-256 hash.
Usage in `no_std` environments is currently planned but not yet implemented.
## Stability Policy
`omnibor` does intend to follow semantic versioning when publishing new versions.
It is currently pre-`1.0`, which for us means we do not generally aim for
stability of the APIs exposed, as we are still iterating and designing what
we consider to be an ideal API for future stabilization.
That said, we do not break stability in point releases.
New version inferences are supported by the use of conventional commits which
mark the introduction of new features or fixing of bugs. When new releases of
`omnibor` are made, `git-cliff` checks our requested version bump against its
determination of the correct version bump based on the `CHANGELOG.md`, and
produces a release error if it believes we're requesting to bump the wrong
version. This helps defend against accidentally-incorrect version bumps which
would violate semantic versioning.
### Minimum Supported Rust Version (MSRV)
This crate does not maintain a Minimum Supported Rust Version, and generally
tracks the latest Rust stable version.
## Contributing
We recommend checking out the full [`CONTRIBUTING.md`] for the OmniBOR Rust
project, which outlines our process.
## License
All of the OmniBOR Rust implementation is Apache 2.0 licensed. Contributions
to `omnibor` are assumed to be made in compliance with the Apache 2.0 license.
[OmniBOR]: https://omnibor.io
[OmniBOR spec]: https://github.com/omnibor/spec
[features]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#choosing-features
[`CONTRIBUTING.md`]: https://github.com/omnibor/omnibor-rs/blob/main/CONTRIBUTING.md