Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.9 kB · 101 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102//! static knot identity: did:web document without a PDS claim, and the//! fixed service bodies (version / owner / health).
use anyhow::Context as _;use base64::Engine as _;use knot_runtime::{OsEntropy, PublicKeyBytes};use knot_secrets::{MasterKey, SealedStore};use knot_types::KnotServiceUrl;
use crate::config::ValidatedConfig;
/// wire version: knot2 is v1.15.0; the static knot advertises its derivative.pub const STATIC_VERSION: &str = "v1.15.0-static.1";
/// capabilities the static server actually implements. never `knot-acl`, never `atproto-firehose`.pub const CAPABILITIES: [&str; 1] = ["repo-did-input"];
pub fn version_body() -> serde_json::Value { serde_json::json!({ "version": STATIC_VERSION, "capabilities": CAPABILITIES, })}
pub fn owner_body(config: &ValidatedConfig) -> serde_json::Value { serde_json::json!({ "owner": config.owner.as_str() })}
pub fn health_body() -> serde_json::Value { serde_json::json!({ "version": format!("knot-static {STATIC_VERSION}") })}
pub(crate) fn load_master_key(config: &ValidatedConfig) -> anyhow::Result<MasterKey> { let raw = std::env::var(&config.master_key_env).with_context(|| { format!( "read master key from environment variable {}", config.master_key_env ) })?; let bytes = base64::engine::general_purpose::STANDARD .decode(raw.trim()) .context("decode master key as base64")?; MasterKey::new(bytes).context("master key from environment")}
/// load the knot's public signing key from the configured sealed key store.pub fn load_knot_public_key(config: &ValidatedConfig) -> anyhow::Result<PublicKeyBytes> { let master_key = load_master_key(config)?; let secrets = SealedStore::open(&config.sealed_key_file, &master_key, Box::new(OsEntropy)) .context("open sealed key store")?; secrets .public_key(&config.knot_did) .context("retrieve knot signing public key")}
/// static knot DID document: same verification method as knot2, one TangledKnot/// service, no atproto_pds.pub fn knot_did_document(config: &ValidatedConfig) -> anyhow::Result<serde_json::Value> { let signing_key = load_knot_public_key(config)?; knot_did_document_from_key(config, &signing_key)}
/// generate the static knot DID document given the resolved public signing key.pub fn knot_did_document_from_key( config: &ValidatedConfig, signing_key: &PublicKeyBytes,) -> anyhow::Result<serde_json::Value> { let service_url = KnotServiceUrl::new(config.service_url()?.to_string()) .context("parse knot service URL for DID document")?; let mut doc = knot_atproto::knot_did_document(&config.knot_did, signing_key, &service_url); strip_pds_service(&mut doc); Ok(doc)}
/// truthful minimal identity (packet §3): static knots serve no PDS, so the/// atproto_pds service from knot2's production document is stripped.fn strip_pds_service(doc: &mut serde_json::Value) { if let Some(services) = doc.get_mut("service").and_then(|s| s.as_array_mut()) { services.retain(|s| s.get("id").and_then(|id| id.as_str()) != Some("#atproto_pds")); }}
#[cfg(test)]mod did_doc_tests { use super::*;
#[test] fn did_document_has_no_pds_service() { let mut doc = serde_json::json!({ "service": [ {"id": "#tangled_knot", "type": "TangledKnot", "serviceEndpoint": "https://git.klbr.net"}, {"id": "#atproto_pds", "type": "AtprotoPersonalDataServer", "serviceEndpoint": "https://git.klbr.net"} ] }); strip_pds_service(&mut doc); let services = doc["service"].as_array().unwrap(); assert_eq!(services.len(), 1); assert_eq!(services[0]["type"], "TangledKnot"); assert!(doc.to_string().find("atproto_pds").is_none()); }}