holger-recipe/src/downstream_ron.rs
//! **A downstream's declaration** (lane OX-WGDS3, 2026-10-28) — the `holger.ron` a
//! downstream's medium (`packaging::downstream_installer`) carries on its release.
//!
//! One downstream, one upstream (lane HOL-WGDS's two ways in):
//!
//! * **`via: Front`** — it mirrors through its upstream estate's public front
//! (`https://…`, the front's repository route), verifying the front's certificate with the CA
//! staged beside this declaration ([`crate::packaging::DOWNSTREAM_CA_STAGED`]), under a TLS
//! name of its own when the address it dials is not the certificate's (`ron_server_name`);
//! * **`via: Wireguard`** — it mirrors through the front's downstream interface
//! (`http://10.46.0.1:50070`, main's sync door), the tunnel brought up from the signed
//! invite: handed through the box's door (`POST /-/sync/upstreams/invite?upstream=<up>`, kept
//! as `holger-sync/enrolled-<up>.json`), or a stick's file at [`DownstreamRon::invite_path`].
//!
//! What it serves: the raw repository `bundles`, mirrored from the upstream's `bundles`,
//! behind the intake chain's four repositories (the shape lane HOL-WGDS's KVM lab proved,
//! 29/29), on the box's doors `0.0.0.0:50051` (gRPC) and `0.0.0.0:8443` (HTTP). Reads are
//! open (`access: (reads: Open)`): a downstream serves its site's build systems. ONE static
//! bearer is Admin, Repository Admin and Auditor on it — the operator's (the ONE-box gate's)
//! way to read its sync key and board and to hand it its invite.
//!
//! Pure: no file system, wasm32-safe like the rest of the recipe.
use crate::packaging::{BOX_HOLGER_DATA, DOWNSTREAM_CA_STAGED};
/// The front's downstream interface's door (holger-downstream `via::HUB_ADDR`:`via::DOOR_PORT`).
pub const WIREGUARD_DOOR: &str = "http://10.46.0.1:50070";
/// The principal the declaration's bearer signs in as.
pub const OPERATOR: &str = "gate";
/// The repository a downstream mirrors and serves.
pub const BUNDLES: &str = "bundles";
/// The intake chain's repositories, in chain order (a downstream's gateway serves through them).
pub const INTAKE_REPOS: [&str; 4] = ["incoming", "quarantine", "approved", "production"];
/// How often the mirror asks its upstream (seconds).
pub const EVERY_SECS: u64 = 15;
/// How a downstream reaches its upstream.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Via {
/// The upstream's public front, over TLS; `server_name`: the certificate's name when the
/// address dialled is not it; `authority`: the calls' `:authority` when it is not that name
/// (a front whose certificate is `<estate>`'s routes `repo.<estate>` by `:authority`).
Front {
server_name: Option<String>,
authority: Option<String>,
},
/// The front's downstream interface, from the signed invite.
Wireguard,
}
impl Via {
/// The word (`front` | `wireguard`), as main's enrolment door spells it.
#[must_use]
pub fn word(&self) -> &'static str {
match self {
Via::Front { .. } => "front",
Via::Wireguard => "wireguard",
}
}
}
/// One downstream's declaration.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DownstreamRon {
/// Its sync name (what its upstream enrols).
pub name: String,
/// Its upstream's sync name and Ed25519 key (hex, `GET /-/sync/key` on the upstream).
pub upstream: String,
pub upstream_key: String,
pub via: Via,
/// The mirror's endpoint: the front (`https://<addr>:<port>`) or [`WIREGUARD_DOOR`].
pub mirror: String,
/// The operator's bearer (Admin, Repository Admin, Auditor on this box).
pub bearer: String,
/// The data root on the box.
pub data: String,
/// Where the release's files are (the staged CA).
pub release: String,
}
/// Pure: a name that is safe in a file name and a RON string.
fn plain(s: &str) -> bool {
!s.is_empty()
&& s.len() <= 63
&& s.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
}
impl DownstreamRon {
/// A downstream on a box (the data root [`BOX_HOLGER_DATA`], the release root
/// [`crate::estate_ron::RELEASE_ROOT`]); every word checked, refused by name.
pub fn on_a_box(
name: &str,
upstream: &str,
upstream_key: &str,
via: Via,
mirror: &str,
bearer: &str,
) -> Result<DownstreamRon, String> {
if !plain(name) {
return Err(format!("[downstream-ron-name] `{name}`: a downstream's name is 1-63 of a-z, A-Z, 0-9, - and _"));
}
// The upstream's sync name: an estate's is its domain (`test3.holger.rs`).
if upstream.is_empty()
|| upstream.len() > 253
|| !upstream
.chars()
.all(|c| c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '.'))
{
return Err(format!("[downstream-ron-upstream] `{upstream}`: the upstream's sync name (`GET /-/sync/key` on it) is 1-253 of a-z, A-Z, 0-9, -, _ and ."));
}
let key = upstream_key.trim().to_ascii_lowercase();
if key.len() != 64 || !key.chars().all(|c| c.is_ascii_hexdigit()) {
return Err(format!("[downstream-ron-key] the upstream's sync key is 64 hex digits (`GET /-/sync/key` on it), not `{upstream_key}`"));
}
let wants = match via {
Via::Front { .. } => "https://",
Via::Wireguard => "http://",
};
if !mirror.starts_with(wants)
|| mirror.contains('"')
|| mirror.chars().any(char::is_whitespace)
{
return Err(format!(
"[downstream-ron-mirror] `{mirror}`: a via: {} downstream mirrors from `{wants}…`",
via.word()
));
}
if let Via::Front {
server_name,
authority,
} = &via
{
for (n, tag) in [
(server_name, "[downstream-ron-tls-name]"),
(authority, "[downstream-ron-authority]"),
] {
if let Some(n) = n {
if n.is_empty()
|| !n
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '.')
{
return Err(format!("{tag} `{n}`: a DNS name"));
}
}
}
}
if bearer.len() < 32
|| !bearer
.chars()
.all(|c| c.is_ascii_graphic() && c != '"' && c != '\\')
{
return Err("[downstream-ron-bearer] the operator's bearer is at least 32 printable characters, no quote or backslash".into());
}
Ok(DownstreamRon {
name: name.into(),
upstream: upstream.into(),
upstream_key: key,
via,
mirror: mirror.into(),
bearer: bearer.into(),
data: BOX_HOLGER_DATA.into(),
release: crate::estate_ron::RELEASE_ROOT.into(),
})
}
/// **Where a `via: Wireguard` downstream looks for a stick's invite file** — under the sync
/// state's directory (`holger-sync/`, on the data disk). The box's invite door keeps what it
/// is handed as `holger-sync/enrolled-<up>.json`, which every later start reads first.
#[must_use]
pub fn invite_path(&self) -> String {
format!(
"{}/holger-sync/invite-{}.json",
self.data.trim_end_matches('/'),
self.upstream.replace(
|c: char| !(c.is_ascii_alphanumeric() || c == '-' || c == '_'),
"_"
)
)
}
/// Where the front's CA is on the box (the medium's `downstream_ca`, on the release).
#[must_use]
pub fn ca_path(&self) -> String {
format!(
"{}/{DOWNSTREAM_CA_STAGED}",
self.release.trim_end_matches('/')
)
}
}
/// **A downstream's `sandbox:`** (lane cds4, plan row HOL-CDS-4): its jobs under Heimdall's
/// runner over the laid sandbox under `<d>/sandbox`, crun over the laid worker rootfs its named
/// fallback, the released verify-bundle guests under the korp root the medium stages on its
/// `release` (`plugin_trust_root`), as the main's (`estate_ron`). The caller closes the intake
/// block after it (`{sandbox})),`).
fn sandbox_line(d: &str, release: &str) -> String {
let sb = format!("{d}/sandbox");
let korp = format!(
"{}/{}",
release.trim_end_matches('/'),
crate::estate_ron::KORP_ROOT_STAGED
);
format!(
"sandbox: Some((engine: heimdall, crun: \"{sb}/crun\", rootfs: Some(\"{sb}/worker/rootfs\"), work_dir: Some(\"{sb}/jobs\"), state_dir: Some(\"{sb}/state\"), \
heimdall: Some((image_layout: \"{sb}/oci\", rootfs_tar: Some(\"{sb}/holger-scan-worker.rootfs.tar\"), shim: Some(\"{sb}/heimdall-container-shim\"), work_dir: Some(\"{sb}/heimdall\"), \
guests: Some(\"{sb}/heimdall-guests\"), guests_trust_root: Some(\"{korp}\")))))"
)
}
/// **Render the declaration.**
#[must_use]
pub fn render(r: &DownstreamRon) -> String {
let d = r.data.trim_end_matches('/');
let repo = |name: &str| {
format!(
" (ron_name: \"{name}\", ron_repo_type: \"raw\", ron_upstreams: [], ron_in: None,\n\
\x20 ron_out: Some((ron_storage_endpoint: \"store\", ron_exposed_endpoint: \"doors\")),\n\
\x20 ron_data_dir: Some(\"{d}/store/{name}\")),\n"
)
};
let mut s = format!(
"// GENERATED by holger-recipe `downstream_ron` (cargo xtask downstream-media). Do not edit on the box.\n\
// The downstream `{}` of `{}`, via {}.\n(\n repositories: [\n",
r.name,
r.upstream,
r.via.word()
);
s.push_str(&repo(BUNDLES));
for name in INTAKE_REPOS {
s.push_str(&repo(name));
}
s.push_str(" ],\n");
s.push_str(" // insecure: the appliance serves its LAN in clear text until it carries a certificate\n // (HOL-NCSC: the choice is written down; a TLS door is a follow-up).\n exposed_endpoints: [\n (ron_name: \"doors\", ron_url: \"0.0.0.0:50051\", ron_http_url: Some(\"0.0.0.0:8443\"), insecure: true),\n ],\n");
s.push_str(&format!(" storage_endpoints: [\n (ron_name: \"store\", ron_storage_type: \"znippy\", ron_path: \"{d}/store\"),\n ],\n"));
s.push_str(&format!(
" audit: (dir: \"{d}/audit\", enabled: true),\n"
));
s.push_str(&format!(
" auth: Some((\n\
\x20 methods: [StaticToken(subject: \"{OPERATOR}\", token: Some(\"{}\"))],\n\
\x20 roles: {{\"{OPERATOR}\": Admin}},\n\
\x20 require_auth_for_reads: false,\n\
\x20 duties: {{\"{OPERATOR}\": [RepositoryAdmin, Auditor]}},\n\
\x20 )),\n",
r.bearer
));
s.push_str(" access: (reads: Open, front: Open),\n");
// It mirrors from its one upstream: the fetching downstream (`--features fetch`, lane
// HOL-CDS). The default `boundary: OneWay` would refuse the `mirror:` block below at start.
s.push_str(" boundary: Fetch,\n");
let stages = INTAKE_REPOS
.iter()
.map(|n| format!("(name: \"{n}\", repo: \"{n}\")"))
.collect::<Vec<_>>()
.join(", ");
let [incoming, quarantine, approved, production] = INTAKE_REPOS;
let sandbox = sandbox_line(d, &r.release);
s.push_str(&format!(
" promotion: Some((\n\
\x20 ladder_name: \"intake\",\n\
\x20 stages: [{stages}],\n\
\x20 intake: Some((incoming: \"{incoming}\", quarantine: \"{quarantine}\", approved: \"{approved}\", production: \"{production}\", approvals: 1, scan: None,\n\
\x20 rules: (sandbox: required),\n\
\x20 {sandbox})),\n\
\x20 )),\n"
));
let credential = match &r.via {
Via::Front {
server_name,
authority,
} => {
let name = server_name
.as_ref()
.map(|n| format!(", ron_server_name: Some(\"{n}\")"))
.unwrap_or_default();
let at = authority
.as_ref()
.map(|n| format!(", ron_authority: Some(\"{n}\")"))
.unwrap_or_default();
format!("Tls(ron_ca_cert: Some(\"{}\"){name}{at})", r.ca_path())
}
Via::Wireguard => "Anonymous".to_string(),
};
s.push_str(&format!(
" mirror: Some((\n\
\x20 ron_state_dir: \"holger-mirror\",\n\
\x20 ron_sources: [\n\
\x20 (ron_name: \"{up}\", ron_kind: Holger, ron_endpoint: \"{ep}\", ron_credential: {credential}, ron_every_secs: {EVERY_SECS},\n\
\x20 ron_repositories: [(ron_from: \"{BUNDLES}\", ron_to: \"{BUNDLES}\", ron_unproven: TrustSize)]),\n\
\x20 ],\n\
\x20 )),\n",
up = r.upstream,
ep = r.mirror
));
let upstream = match &r.via {
Via::Front { .. } => format!("(name: \"{}\", key: \"{}\")", r.upstream, r.upstream_key),
Via::Wireguard => format!(
"(name: \"{}\", key: \"{}\", url: Some(\"{WIREGUARD_DOOR}\"), invite: Some(\"{}\"))",
r.upstream,
r.upstream_key,
r.invite_path()
),
};
s.push_str(&format!(
" sync: Some((name: \"{}\", upstreams: [{upstream}])),\n)\n",
r.name
));
s
}
/// The principal the one-way declaration's bearer signs in as: the site's admin.
pub const SITE_ADMIN: &str = "admin";
/// **A ONE-WAY downstream's declaration** (lane HOL-CDS-5, owner 2026-10-30): the appliance
/// `holger-downstream-oneway-installer` lays. It dials nothing (`boundary: OneWay`); its
/// packages come in only through its inbox; every trust anchor is a file of the medium's
/// release (the admin provisions them when the medium is composed), never of the data disk.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OneWayRon {
/// Its name (the declaration's comment, the box's word for itself).
pub name: String,
/// The security domain it serves (`domain:`, in every answer's `X-Holger-Domain`).
pub domain: String,
/// The site admin's bearer (Admin, Repository Admin and Auditor): the admin's way to
/// authorize the first import (`POST /-/bundle/first-import`) and read the audit.
pub bearer: String,
/// The data root on the box.
pub data: String,
/// Where the release's files are (the staged trust).
pub release: String,
}
impl OneWayRon {
/// A one-way downstream on a box; every word checked, refused by name.
pub fn on_a_box(name: &str, domain: &str, bearer: &str) -> Result<OneWayRon, String> {
if !plain(name) {
return Err(format!("[downstream-ron-name] `{name}`: a downstream's name is 1-63 of a-z, A-Z, 0-9, - and _"));
}
if domain.trim().is_empty()
|| domain.len() > 64
|| domain.trim() != domain
|| !domain
.bytes()
.all(|b| (0x20..0x7f).contains(&b) && b != b'"' && b != b'\\')
{
return Err(format!("[downstream-ron-domain] `{domain}`: the domain label is 1-64 printable characters, no quote or backslash"));
}
if bearer.len() < 32
|| !bearer
.chars()
.all(|c| c.is_ascii_graphic() && c != '"' && c != '\\')
{
return Err("[downstream-ron-bearer] the site admin's bearer is at least 32 printable characters, no quote or backslash".into());
}
Ok(OneWayRon {
name: name.into(),
domain: domain.into(),
bearer: bearer.into(),
data: BOX_HOLGER_DATA.into(),
release: crate::estate_ron::RELEASE_ROOT.into(),
})
}
fn on_release(&self, file: &str) -> String {
format!("{}/{file}", self.release.trim_end_matches('/'))
}
}
/// **Render the one-way declaration.**
#[must_use]
pub fn render_one_way(r: &OneWayRon) -> String {
use crate::packaging::{ONEWAY_ROOT_STAGED, ONEWAY_SIGNER_STAGED, ONEWAY_TRUST_POLICY_STAGED};
let d = r.data.trim_end_matches('/');
let mut s = format!(
"// GENERATED by holger-recipe `downstream_ron::render_one_way` (cargo xtask downstream-media --oneway). Do not edit on the box.\n\
// The ONE-WAY downstream `{}`: packages only through its inbox; it dials nothing.\n(\n boundary: OneWay,\n domain: \"{}\",\n trust: (first_import: Admin),\n repositories: [\n",
r.name, r.domain
);
for name in INTAKE_REPOS {
s.push_str(&format!(
" (ron_name: \"{name}\", ron_repo_type: \"raw\", ron_upstreams: [], ron_in: None,\n\
\x20 ron_out: Some((ron_storage_endpoint: \"store\", ron_exposed_endpoint: \"doors\")),\n\
\x20 ron_data_dir: Some(\"{d}/store/{name}\")),\n"
));
}
s.push_str(" ],\n");
s.push_str(" // insecure: the appliance serves its site's LAN in clear text until its medium carries a\n // certificate (HOL-NCSC: the choice is written down; a TLS door is a follow-up).\n exposed_endpoints: [\n (ron_name: \"doors\", ron_url: \"0.0.0.0:50051\", ron_http_url: Some(\"0.0.0.0:8443\"), insecure: true),\n ],\n");
s.push_str(&format!(" storage_endpoints: [\n (ron_name: \"store\", ron_storage_type: \"znippy\", ron_path: \"{d}/store\"),\n ],\n"));
s.push_str(&format!(
" audit: (dir: \"{d}/audit\", enabled: true),\n"
));
s.push_str(&format!(
" auth: Some((\n\
\x20 methods: [StaticToken(subject: \"{SITE_ADMIN}\", token: Some(\"{}\"))],\n\
\x20 roles: {{\"{SITE_ADMIN}\": Admin}},\n\
\x20 require_auth_for_reads: false,\n\
\x20 duties: {{\"{SITE_ADMIN}\": [RepositoryAdmin, Auditor]}},\n\
\x20 )),\n",
r.bearer
));
s.push_str(" access: (reads: Open, front: Open),\n");
s.push_str(&format!(
" attestation: Some((\n trust_roots: [\"{}\"],\n enrolled_signers: [\"{}\"],\n )),\n",
r.on_release(ONEWAY_ROOT_STAGED),
r.on_release(ONEWAY_SIGNER_STAGED)
));
let stages = INTAKE_REPOS
.iter()
.map(|n| format!("(name: \"{n}\", repo: \"{n}\")"))
.collect::<Vec<_>>()
.join(", ");
let [incoming, quarantine, approved, production] = INTAKE_REPOS;
let sandbox = sandbox_line(d, &r.release);
s.push_str(&format!(
" promotion: Some((\n\
\x20 ladder_name: \"intake\",\n\
\x20 stages: [{stages}],\n\
\x20 intake: Some((incoming: \"{incoming}\", quarantine: \"{quarantine}\", approved: \"{approved}\", production: \"{production}\", approvals: 1, scan: None, trust_policy: Some(\"{}\"),\n\
\x20 rules: (sandbox: required),\n\
\x20 {sandbox})),\n\
\x20 )),\n)\n",
r.on_release(ONEWAY_TRUST_POLICY_STAGED)
));
s
}
#[cfg(test)]
mod tests {
use super::*;
const KEY: &str = "ab12ab12ab12ab12ab12ab12ab12ab12ab12ab12ab12ab12ab12ab12ab12ab12";
const BEARER: &str = "gate-bearer-of-sufficient-length-0123456789";
#[test]
fn a_front_downstream_mirrors_the_front_over_tls_with_its_ca_and_name() {
let r = DownstreamRon::on_a_box(
"lab-1",
"test3.holger.rs",
KEY,
Via::Front {
server_name: Some("repo.test3.holger.rs".into()),
authority: None,
},
"https://10.0.2.2:40443",
BEARER,
)
.unwrap();
let t = render(&r);
assert!(t.contains("ron_endpoint: \"https://10.0.2.2:40443\", ron_credential: Tls(ron_ca_cert: Some(\"/run/korp/release/downstream-ca.pem\"), ron_server_name: Some(\"repo.test3.holger.rs\"))"), "{t}");
assert!(t.contains(&format!("sync: Some((name: \"lab-1\", upstreams: [(name: \"test3.holger.rs\", key: \"{KEY}\")])),")), "{t}");
assert!(
!t.contains("invite"),
"a front downstream has no invite: {t}"
);
// Lane HOL-CDS: a downstream that mirrors is `boundary: Fetch` (built with `fetch`); the
// default OneWay refuses a `mirror:` block at start (holger-boundary-1).
assert!(t.contains(" boundary: Fetch,\n"), "{t}");
assert!(
t.contains(&format!(
"StaticToken(subject: \"gate\", token: Some(\"{BEARER}\"))"
)),
"{t}"
);
assert!(t.contains("access: (reads: Open, front: Open)"), "{t}");
assert!(
t.contains("ron_data_dir: Some(\"/data/holger/store/bundles\")"),
"{t}"
);
// The certificate's name and the route's `:authority` apart (the bench front's certificate is
// the site's own; its repository route is `repo.<site>`).
let apart = DownstreamRon::on_a_box(
"lab-1",
"test3.holger.rs",
KEY,
Via::Front {
server_name: Some("test3.holger.rs".into()),
authority: Some("repo.test3.holger.rs".into()),
},
"https://10.0.2.2:40443",
BEARER,
)
.unwrap();
assert!(render(&apart).contains("ron_server_name: Some(\"test3.holger.rs\"), ron_authority: Some(\"repo.test3.holger.rs\"))"), "{}", render(&apart));
assert!(DownstreamRon::on_a_box(
"lab-1",
"up",
KEY,
Via::Front {
server_name: None,
authority: Some("a b".into())
},
"https://x",
BEARER
)
.unwrap_err()
.contains("[downstream-ron-authority]"));
// Without a name the certificate's own host is dialled.
let plain = DownstreamRon::on_a_box(
"lab-1",
"up",
KEY,
Via::Front {
server_name: None,
authority: None,
},
"https://repo.up.example:443",
BEARER,
)
.unwrap();
assert!(render(&plain)
.contains("Tls(ron_ca_cert: Some(\"/run/korp/release/downstream-ca.pem\"))"));
}
#[test]
fn a_wireguard_downstream_mirrors_mains_sync_door_from_its_invite() {
let r = DownstreamRon::on_a_box(
"lab-2",
"test3.holger.rs",
&KEY.to_uppercase(),
Via::Wireguard,
WIREGUARD_DOOR,
BEARER,
)
.unwrap();
assert_eq!(
r.invite_path(),
"/data/holger/holger-sync/invite-test3_holger_rs.json"
);
let t = render(&r);
assert!(
t.contains("ron_endpoint: \"http://10.46.0.1:50070\", ron_credential: Anonymous"),
"{t}"
);
assert!(t.contains(&format!("(name: \"test3.holger.rs\", key: \"{KEY}\", url: Some(\"http://10.46.0.1:50070\"), invite: Some(\"/data/holger/holger-sync/invite-test3_holger_rs.json\"))")), "the key lower-cased, the invite under the sync state: {t}");
assert!(!t.contains("downstream-ca.pem"), "{t}");
assert!(t.contains(" boundary: Fetch,\n"), "{t}");
}
#[test]
fn every_word_is_checked_and_refused_by_name() {
let ok = |n: &str, up: &str, k: &str, v: Via, m: &str, b: &str| {
DownstreamRon::on_a_box(n, up, k, v, m, b)
};
let front = || Via::Front {
server_name: None,
authority: None,
};
for (r, tag) in [
(
ok("lab 1", "up", KEY, front(), "https://x", BEARER),
"[downstream-ron-name]",
),
(
ok("lab-1", "u\"p", KEY, front(), "https://x", BEARER),
"[downstream-ron-upstream]",
),
(
ok("lab-1", "up", "abc", front(), "https://x", BEARER),
"[downstream-ron-key]",
),
(
ok("lab-1", "up", KEY, front(), "http://x", BEARER),
"[downstream-ron-mirror]",
),
(
ok("lab-1", "up", KEY, Via::Wireguard, "https://x", BEARER),
"[downstream-ron-mirror]",
),
(
ok(
"lab-1",
"up",
KEY,
Via::Front {
server_name: Some("a b".into()),
authority: None,
},
"https://x",
BEARER,
),
"[downstream-ron-tls-name]",
),
(
ok("lab-1", "up", KEY, front(), "https://x", "short"),
"[downstream-ron-bearer]",
),
] {
assert!(
r.as_ref().is_err_and(|e| e.starts_with(tag)),
"{tag}: {r:?}"
);
}
}
}