mod command_runner;
mod composition;
#[allow(dead_code)]
mod destruction_evidence;
mod event_signing;
#[allow(dead_code)]
mod dns_proxy;
mod ebpf_flow;
#[allow(dead_code)]
mod linux_cgroup;
mod linux_isolation;
#[cfg(target_os = "linux")]
mod linux_mount;
#[cfg(target_os = "linux")]
mod linux_net;
#[cfg(target_os = "linux")]
mod linux_seccomp;
mod network_policy;
mod nft_counters;
mod per_flow;
mod proxy_activation;
mod reconcile;
#[allow(dead_code)]
mod resolver_refresh;
mod runtime_secret;
#[allow(dead_code)]
mod sni_proxy;
mod spec_input;
mod supervisor;
mod supervisor_helpers;
mod trust_keyset_load;
mod trust_plane_observability;
use std::ffi::OsString;
use std::path::PathBuf;
use anyhow::Context;
use cellos_core::{
admission_decision_data_v1, enforce_derivation_scope_policy, validate_execution_cell_document,
verify_authority_derivation, AdmissionDecisionReason, AuthorityCapability, EnforcementBinding,
ExecutionCellDocument, ExecutionCellSpec, ADMISSION_ALLOWED_TYPE, ADMISSION_REJECTED_TYPE,
};
use composition::{
build_admission_receipt_signer, build_supervisor, emit_startup_banner,
enforce_authority_derivation_requirement, enforce_deployment_profile, enforce_host_baseline,
enforce_isolation_default, enforce_kubernetes_namespace_placement, enforce_telemetry_declared,
load_authority_keys, resolve_deployment_mode,
};
use event_signing::StandaloneEventSigner;
use spec_input::{read_cell_spec, spec_sha256};
use supervisor_helpers::cloud_event;
use trust_keyset_load::{
load_and_verify_ceiling_from_env, load_trust_verify_keys_from_env, CeilingLoadOutcome,
CeilingVerifiedDetails,
};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::Layer;
let fmt_layer = tracing_subscriber::fmt::layer()
.with_writer(std::io::stderr)
.with_filter(cellos_core::observability::redacted_filter());
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.with(fmt_layer)
.init();
cellos_core::crypto::power_on_self_test()
.map_err(|e| anyhow::anyhow!("crypto power-on self-test failed (fail-stop): {e}"))?;
enforce_deployment_profile()?;
let deployment_mode = resolve_deployment_mode()?;
enforce_isolation_default(deployment_mode)?;
emit_startup_banner(deployment_mode);
let host_baseline = enforce_host_baseline(deployment_mode)?;
let args: Vec<OsString> = std::env::args_os().skip(1).collect();
if let Some(subcommand) = args.first().and_then(|s| s.to_str()) {
match subcommand {
"secret" => return runtime_secret::cli_main(&args[1..]).await,
"--version" | "-V" => {
println!("cellos-supervisor {}", env!("CARGO_PKG_VERSION"));
return Ok(());
}
_ => {}
}
}
let validate_only = args
.first()
.and_then(|s| s.to_str())
.map(|s| s == "--validate")
.unwrap_or(false);
let spec_arg_index = if validate_only { 1 } else { 0 };
let spec_path = args
.get(spec_arg_index)
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("contracts/examples/execution-cell-minimal.valid.json"));
let raw = read_cell_spec(&spec_path)?;
let raw_spec_hash = spec_sha256(&raw);
let doc: ExecutionCellDocument =
serde_json::from_str(&raw).context("parse ExecutionCellDocument")?;
validate_execution_cell_document(&doc).map_err(|e| anyhow::anyhow!("{e}"))?;
enforce_authority_derivation_requirement(&doc)?;
enforce_telemetry_declared(&doc)?;
enforce_kubernetes_namespace_placement(&doc)?;
if validate_only {
let validate_run_id = std::env::var("CELLOS_RUN_ID").unwrap_or_else(|_| "validate".into());
let summary = composition::build_validation_summary(
&doc,
&validate_run_id,
&raw_spec_hash,
&spec_path,
);
println!(
"{}",
serde_json::to_string_pretty(&summary).unwrap_or_default()
);
return Ok(());
}
let authority_keys = load_authority_keys()?;
let allow_universal = scoped_tokens_permissive_mode_enabled();
let mut universal_token_accepted_in_permissive_mode = false;
if let Some(token) = doc.spec.authority.authority_derivation.as_ref() {
verify_authority_derivation(&doc.spec, token, &authority_keys)
.map_err(|e| anyhow::anyhow!("{e}"))?;
enforce_derivation_scope_policy(token, allow_universal)
.map_err(|e| anyhow::anyhow!("{e}"))?;
if allow_universal && token.parent_run_id.is_none() {
universal_token_accepted_in_permissive_mode = true;
}
}
let authority_keys = std::sync::Arc::new(authority_keys);
let run_id = std::env::var("CELLOS_RUN_ID").unwrap_or_else(|_| "run-local-001".into());
let admission_signer = build_admission_receipt_signer(&doc, &run_id).await?;
emit_host_baseline_receipt(&host_baseline, &admission_signer).await;
enforce_authority_ceiling(&doc.spec, &raw_spec_hash, &run_id, &admission_signer).await?;
let mut supervisor = build_supervisor(&doc, &run_id, authority_keys).await?;
if deployment_mode.is_airgapped() {
reconcile::run_startup_reconcile(&doc, &run_id, &supervisor.event_sink).await?;
}
supervisor.universal_token_accepted_in_permissive_mode =
universal_token_accepted_in_permissive_mode;
supervisor.run(&doc, &run_id, Some(&raw_spec_hash)).await
}
async fn emit_host_baseline_receipt(
attestation: &cellos_core::HostBaselineAttestationV1,
signer: &StandaloneEventSigner,
) {
let event = match cellos_core::host_baseline_event(attestation) {
Ok(event) => event,
Err(e) => {
tracing::warn!(
target: "cellos.supervisor.baseline",
error = %e,
"host-baseline receipt: building the event failed (advisory — startup continues)"
);
return;
}
};
if let Err(e) = signer.emit_decision(&event).await {
tracing::warn!(
target: "cellos.supervisor.baseline",
error = %e,
"host-baseline receipt: emit failed (advisory — startup continues)"
);
}
}
fn scoped_tokens_permissive_mode_enabled() -> bool {
match std::env::var("CELLOS_REQUIRE_SCOPED_DERIVATION_TOKENS") {
Ok(raw) => {
let t = raw.trim().to_ascii_lowercase();
matches!(t.as_str(), "0" | "false" | "no" | "off")
}
Err(_) => false, }
}
const CEILING_PREDICATE: &str = "ceiling.is_superset_of(spec.authority)";
fn authority_ceiling_required() -> bool {
let explicit = std::env::var("CELLOS_REQUIRE_AUTHORITY_CEILING")
.map(|v| {
let t = v.trim().to_ascii_lowercase();
matches!(t.as_str(), "1" | "true" | "yes" | "on")
})
.unwrap_or(false);
explicit || deployment_profile_is_hardened()
}
fn deployment_profile_is_hardened() -> bool {
let raw = std::env::var("CELLOS_DEPLOYMENT_PROFILE").unwrap_or_default();
let t = raw.trim().to_ascii_lowercase();
t.is_empty() || t == "hardened"
}
fn ceiling_enforcement_binding() -> EnforcementBinding {
if cfg!(target_os = "linux") {
EnforcementBinding::LinuxNftables
} else {
EnforcementBinding::DeclaredAudit
}
}
fn populated_uncomparable_dimensions(spec: &ExecutionCellSpec) -> Vec<&'static str> {
let a = &spec.authority;
let mut populated = Vec::new();
if a.filesystem.is_some() {
populated.push("filesystem");
}
if a.network.is_some() {
populated.push("network");
}
if a.dns_authority.is_some() {
populated.push("dns");
}
if a.cdn_authority.is_some() {
populated.push("cdn");
}
populated
}
async fn enforce_authority_ceiling(
spec: &ExecutionCellSpec,
spec_hash: &str,
run_id: &str,
signer: &StandaloneEventSigner,
) -> anyhow::Result<()> {
let required = authority_ceiling_required();
let hardened = deployment_profile_is_hardened();
let binding = ceiling_enforcement_binding();
let keys = load_trust_verify_keys_from_env(required)?;
match load_and_verify_ceiling_from_env(keys.as_ref(), required, std::time::SystemTime::now())? {
CeilingLoadOutcome::NotConfigured => {
emit_ceiling_receipt(
signer,
ADMISSION_ALLOWED_TYPE,
spec,
true,
AdmissionDecisionReason::CeilingDegradedUnconfigured,
spec_hash,
run_id,
binding,
)
.await?;
tracing::warn!(
target: "cellos.supervisor.ceiling",
receipt_signed = signer.is_signing_enabled(),
"authority ceiling not configured and not required; admission proceeds via the \
labeled degraded fail-open path (ceiling_degraded_unconfigured receipt emitted; \
receipt is offline-verifiable only when CELLOS_EVENT_SIGNING is configured)"
);
Ok(())
}
CeilingLoadOutcome::Verified(details) => {
enforce_verified_ceiling(spec, spec_hash, run_id, signer, &details, hardened, binding)
.await
}
}
}
#[allow(clippy::too_many_arguments)]
async fn enforce_verified_ceiling(
spec: &ExecutionCellSpec,
spec_hash: &str,
run_id: &str,
signer: &StandaloneEventSigner,
details: &CeilingVerifiedDetails,
hardened: bool,
binding: EnforcementBinding,
) -> anyhow::Result<()> {
let uncomparable = populated_uncomparable_dimensions(spec);
if !uncomparable.is_empty() {
if hardened {
emit_ceiling_receipt(
signer,
ADMISSION_REJECTED_TYPE,
spec,
false,
AdmissionDecisionReason::CeilingDimensionUncomparable,
spec_hash,
run_id,
binding,
)
.await?;
return Err(anyhow::anyhow!(
"authority ceiling: spec '{}' populates uncomparable authority dimension(s) {:?} \
the ceiling cannot bound; rejected ceiling_dimension_uncomparable under hardened \
(ceilingId {})",
spec.id,
uncomparable,
details.manifest.ceiling_id,
));
}
tracing::warn!(
target: "cellos.supervisor.ceiling",
spec_id = %spec.id,
dimensions = ?uncomparable,
"spec populates authority dimension(s) the ceiling cannot compare; the ceiling does \
NOT bound them (advisory — set CELLOS_DEPLOYMENT_PROFILE=hardened to reject)"
);
}
let claim = AuthorityCapability::from_bundle(&spec.authority);
let admitted = details
.manifest
.ceilings
.iter()
.any(|named| named.ceiling.is_superset_of(&claim));
if admitted {
emit_ceiling_receipt(
signer,
ADMISSION_ALLOWED_TYPE,
spec,
true,
AdmissionDecisionReason::AdmittedWithinCeiling,
spec_hash,
run_id,
binding,
)
.await?;
tracing::info!(
target: "cellos.supervisor.ceiling",
spec_id = %spec.id,
ceiling_id = %details.manifest.ceiling_id,
manifest_digest = %details.manifest_digest,
"spec admitted within org-root authority ceiling"
);
return Ok(());
}
emit_ceiling_receipt(
signer,
ADMISSION_REJECTED_TYPE,
spec,
false,
AdmissionDecisionReason::AuthorityExceedsCeiling,
spec_hash,
run_id,
binding,
)
.await?;
Err(anyhow::anyhow!(
"authority ceiling: spec '{}' declared authority is not a subset of any ceiling in \
manifest '{}'; rejected authority_exceeds_ceiling",
spec.id,
details.manifest.ceiling_id,
))
}
#[allow(clippy::too_many_arguments)]
async fn emit_ceiling_receipt(
signer: &StandaloneEventSigner,
event_ty: &str,
spec: &ExecutionCellSpec,
admitted: bool,
reason: AdmissionDecisionReason,
spec_hash: &str,
run_id: &str,
binding: EnforcementBinding,
) -> anyhow::Result<()> {
let data = admission_decision_data_v1(
spec,
admitted,
reason,
CEILING_PREDICATE,
spec_hash,
Some(run_id),
binding,
&[],
)
.context("build admission-decision receipt payload")?;
let event = cloud_event(event_ty, data);
signer
.emit_decision(&event)
.await
.map_err(|e| anyhow::anyhow!("emit admission-decision receipt: {e}"))?;
signer
.flush()
.await
.map_err(|e| anyhow::anyhow!("flush admission-decision receipt: {e}"))?;
Ok(())
}
#[cfg(test)]
mod ceiling_gate_tests {
use super::*;
use async_trait::async_trait;
use cellos_core::ports::EventSink;
use cellos_core::types::{NamedAuthorityCeiling, OrgAuthorityCeilingManifestV1};
use cellos_core::{AuthorityBundle, CellosError, CloudEventV1, EgressRule};
use std::sync::{Arc, Mutex};
struct CaptureSink(Mutex<Vec<CloudEventV1>>);
impl CaptureSink {
fn new() -> Arc<Self> {
Arc::new(Self(Mutex::new(Vec::new())))
}
fn events(&self) -> Vec<CloudEventV1> {
self.0.lock().unwrap().clone()
}
}
#[async_trait]
impl EventSink for CaptureSink {
async fn emit(&self, event: &CloudEventV1) -> Result<(), CellosError> {
self.0.lock().unwrap().push(event.clone());
Ok(())
}
}
fn unsigned_signer(capture: Arc<CaptureSink>) -> StandaloneEventSigner {
let _g = ENV_MUTEX.lock().unwrap_or_else(|e| e.into_inner());
std::env::remove_var("CELLOS_EVENT_SIGNING");
std::env::remove_var("CELLOS_REDACT_EVENT_FIELDS");
StandaloneEventSigner::from_env(capture as Arc<dyn EventSink>).0
}
static ENV_MUTEX: Mutex<()> = Mutex::new(());
fn egress(host: &str, port: u16) -> EgressRule {
EgressRule {
host: host.into(),
port,
protocol: Some("tcp".into()),
dns_egress_justification: None,
}
}
fn spec_with_authority(authority: AuthorityBundle) -> ExecutionCellSpec {
ExecutionCellSpec {
id: "spec-under-test".into(),
authority,
..Default::default()
}
}
fn ceiling_details(ceiling: AuthorityCapability) -> CeilingVerifiedDetails {
CeilingVerifiedDetails {
manifest: OrgAuthorityCeilingManifestV1 {
schema_version: "1.0.0".into(),
ceiling_id: "ceiling-test".into(),
ceiling_epoch: 1,
ceilings: vec![NamedAuthorityCeiling {
name: "default".into(),
ceiling,
}],
not_before: None,
not_after: None,
},
manifest_digest: "sha256:deadbeef".into(),
verified_signer_kid: "org-root".into(),
}
}
fn emitted_reason(capture: &CaptureSink) -> String {
let events = capture.events();
assert_eq!(events.len(), 1, "exactly one receipt expected");
events[0]
.data
.as_ref()
.and_then(|d| d.get("reason"))
.and_then(|v| v.as_str())
.expect("receipt carries a reason")
.to_string()
}
#[tokio::test]
async fn admitted_within_ceiling() {
let capture = CaptureSink::new();
let signer = unsigned_signer(capture.clone());
let spec = spec_with_authority(AuthorityBundle {
egress_rules: Some(vec![egress("api.internal", 443)]),
..Default::default()
});
let details = ceiling_details(AuthorityCapability {
egress_rules: vec![egress("api.internal", 443)],
secret_refs: vec![],
});
enforce_verified_ceiling(
&spec,
"sha256:abc",
"run-1",
&signer,
&details,
true,
EnforcementBinding::LinuxNftables,
)
.await
.expect("subset spec must be admitted");
let events = capture.events();
assert_eq!(events.len(), 1);
assert_eq!(events[0].ty, ADMISSION_ALLOWED_TYPE);
assert_eq!(emitted_reason(&capture), "admitted_within_ceiling");
}
#[tokio::test]
async fn authority_exceeds_ceiling_rejects_after_receipt() {
let capture = CaptureSink::new();
let signer = unsigned_signer(capture.clone());
let spec = spec_with_authority(AuthorityBundle {
egress_rules: Some(vec![egress("0.0.0.0/0", 443)]),
..Default::default()
});
let details = ceiling_details(AuthorityCapability {
egress_rules: vec![egress("api.internal", 443)],
secret_refs: vec![],
});
let err = enforce_verified_ceiling(
&spec,
"sha256:abc",
"run-1",
&signer,
&details,
true,
EnforcementBinding::LinuxNftables,
)
.await
.expect_err("over-broad spec must be rejected");
assert!(format!("{err}").contains("authority_exceeds_ceiling"));
assert_eq!(emitted_reason(&capture), "authority_exceeds_ceiling");
assert_eq!(capture.events()[0].ty, ADMISSION_REJECTED_TYPE);
}
#[tokio::test]
async fn uncomparable_dimension_rejected_under_hardened() {
let capture = CaptureSink::new();
let signer = unsigned_signer(capture.clone());
let spec = spec_with_authority(AuthorityBundle {
filesystem: Some(serde_json::json!({"mounts": ["/data"]})),
..Default::default()
});
let details = ceiling_details(AuthorityCapability::default());
let err = enforce_verified_ceiling(
&spec,
"sha256:abc",
"run-1",
&signer,
&details,
true,
EnforcementBinding::LinuxNftables,
)
.await
.expect_err("populated filesystem under hardened must reject");
assert!(format!("{err}").contains("ceiling_dimension_uncomparable"));
assert_eq!(emitted_reason(&capture), "ceiling_dimension_uncomparable");
assert_eq!(capture.events()[0].ty, ADMISSION_REJECTED_TYPE);
}
#[tokio::test]
async fn uncomparable_dimension_warns_outside_hardened() {
let capture = CaptureSink::new();
let signer = unsigned_signer(capture.clone());
let spec = spec_with_authority(AuthorityBundle {
network: Some(serde_json::json!({"any": true})),
..Default::default()
});
let details = ceiling_details(AuthorityCapability::default());
enforce_verified_ceiling(
&spec,
"sha256:abc",
"run-1",
&signer,
&details,
false,
EnforcementBinding::DeclaredAudit,
)
.await
.expect("outside hardened, uncomparable dimension is advisory only");
assert_eq!(emitted_reason(&capture), "admitted_within_ceiling");
}
#[tokio::test]
async fn empty_ceiling_list_is_deny_all() {
let capture = CaptureSink::new();
let signer = unsigned_signer(capture.clone());
let spec = spec_with_authority(AuthorityBundle {
secret_refs: Some(vec!["prod-db".into()]),
..Default::default()
});
let details = CeilingVerifiedDetails {
manifest: OrgAuthorityCeilingManifestV1 {
schema_version: "1.0.0".into(),
ceiling_id: "deny-all".into(),
ceiling_epoch: 1,
ceilings: vec![],
not_before: None,
not_after: None,
},
manifest_digest: "sha256:00".into(),
verified_signer_kid: "org-root".into(),
};
let err = enforce_verified_ceiling(
&spec,
"sha256:abc",
"run-1",
&signer,
&details,
true,
EnforcementBinding::LinuxNftables,
)
.await
.expect_err("deny-all ceiling must reject a non-empty claim");
assert!(format!("{err}").contains("authority_exceeds_ceiling"));
assert_eq!(emitted_reason(&capture), "authority_exceeds_ceiling");
}
#[tokio::test]
async fn degraded_unconfigured_receipt_shape() {
let capture = CaptureSink::new();
let signer = unsigned_signer(capture.clone());
let spec = spec_with_authority(AuthorityBundle::default());
emit_ceiling_receipt(
&signer,
ADMISSION_ALLOWED_TYPE,
&spec,
true,
AdmissionDecisionReason::CeilingDegradedUnconfigured,
"sha256:abc",
"run-1",
EnforcementBinding::DeclaredAudit,
)
.await
.expect("degraded receipt emits");
assert_eq!(emitted_reason(&capture), "ceiling_degraded_unconfigured");
let events = capture.events();
assert_eq!(events[0].ty, ADMISSION_ALLOWED_TYPE);
assert_eq!(
events[0].data.as_ref().and_then(|d| d.get("admitted")),
Some(&serde_json::Value::Bool(true)),
"degraded path admits (proceeds)"
);
}
}