Skip to main content

holger_intel/
lib.rs

1//! # holger-intel — offline vulnerability intelligence
2//!
3//! Holger's secure side never touches the internet, so its advisory database
4//! has to cross the airgap the same way a firmware release does:
5//!
6//! ```text
7//!  ONLINE                                     │ AIRGAP │            SECURE
8//!  OSV all.zip ─┐                             │        │
9//!  NVD 2.0 ─────┼─ normalize ─ AdvisorySet ─ sign ─ USB ─ verify ─ floor ─ audit ─ local DB ─ scan
10//!  CISA KEV ────┘   (feeds)      (set)      (bundle)       (import)              (db)     (resolve)
11//! ```
12//!
13//! * **No new format.** An intel bundle IS a `holger.update-bundle/v1`, with
14//!   `product = holger.intel/v1` ([`INTEL_PRODUCT`]). The advisory set is its one
15//!   payload (`payload/advisories.json`); the per-feed source record is its
16//!   `Advisory` evidence. The release manifest hashes every member (SHA-256 +
17//!   BLAKE3), the release signature covers the manifest, and the same trust
18//!   policy, two-person rule, trusted clock and anti-rollback floor apply.
19//! * **Anti-rollback.** `core.sequence` is monotonic per
20//!   `(supplier, holger.intel/v1)`; [`import`] refuses a lower sequence, a
21//!   same-sequence replay with other bytes and an absent floor without
22//!   `first_import`, through `update-bundle`'s `RollbackStore`.
23//! * **Fail-closed audit.** [`import`] writes its audit record before the floor
24//!   moves and before the new set goes live; a sink that is off or fails refuses
25//!   the import and leaves the database as it was.
26//! * **Staleness.** The evidence names the bundle sequence and snapshot date;
27//!   [`stale::StalenessRule`] warns after N days and blocks after M.
28//! * **Offline proof.** [`net::IntelNet::offline`] refuses every URL. The
29//!   default build of this crate links no HTTP client at all; `fetch` adds
30//!   `ureq` for the online side only.
31
32pub mod bundle;
33pub mod db;
34pub mod feeds;
35pub mod import;
36pub mod net;
37pub mod resolve;
38pub mod set;
39pub mod stale;
40pub mod subject;
41
42/// The verdict engine and advisory model this crate carries, re-exported so a
43/// consumer scans with exactly these types.
44pub use modgunn;
45/// The time types the evidence and the staleness rule are written in.
46pub use chrono;
47
48pub use bundle::{build_bundle, BuildOptions, BuiltBundle, SignerFiles};
49pub use db::{InstalledIntel, LocalIntelDb};
50pub use feeds::{FeedKind, FeedSpec, RawFeed};
51pub use import::{import, ImportAudit, ImportOutcome, ImportRecord, ImportRequest};
52pub use net::{Fetch, IntelNet, NetError};
53pub use resolve::{
54    fold_staleness, resolve, resolve_local, scan_against, IntelEvidence, IntelScanner, IntelSettings, IntelVerdict, LiveIntel,
55    ResolvedAdvisories,
56};
57pub use set::{AdvisorySet, IntelAdvisory, SourceRecord};
58pub use stale::{Staleness, StalenessRule};
59
60/// The `core.product` every intel bundle carries. The anti-rollback floor is
61/// kept per `(supplier, product)`, so this is what makes the intel sequence its
62/// own monotonic line, separate from any firmware product.
63pub const INTEL_PRODUCT: &str = "holger.intel/v1";
64
65/// The supplier an intel bundle names when the builder is not told another.
66pub const DEFAULT_SUPPLIER: &str = "holger-intel";
67
68/// The bundle member that carries the normalized advisory set.
69pub const ADVISORIES_REL: &str = "advisories.json";
70
71/// Its media type.
72pub const ADVISORIES_MEDIA_TYPE: &str = "application/vnd.holger.intel-advisories+json";
73
74/// The evidence member that records, per feed, where it came from and its hash.
75pub const SOURCES_REL: &str = "intel-sources.json";