feat(storage): per-app/owner/system encryption live: gatekeeper hands seed + fresh flag, storage unlocks layer, init seeds areas from factory/ (empties on new key); rmdir op; test-qemu checks sealed home + reboot persistence

This commit is contained in:
2026-10-28 00:07:41 +01:00
parent e8191be160
commit 9dc751c466
20 changed files with 344 additions and 72 deletions

View File

@@ -2,8 +2,9 @@
//! the same strict parser the permission manager uses:
//!
//! app-image install <root> <manifest.toml> <binary>
//! an installed, pre-approved app: /apps/<id>/, its decision granting
//! everything it asks for, and /data/<id>/ if that includes storage
//! an installed, pre-approved app: /apps/<id>/, and (under factory/,
//! which init seeds the encrypted areas from) its decision granting
//! everything it asks for, and data/<id>/ if that includes storage
//! app-image stage <folder> <manifest.toml> <binary>
//! an app folder the owner can install later (`install <folder>`)
@@ -36,11 +37,11 @@ fn install(root: &Path, manifest: &Path, binary: &Path) -> Result<(), String> {
};
let mut out = [0u8; MAX_DECISION_TEXT];
let n = decision.write(&mut out);
let decisions = root.join("system/permissions");
let decisions = root.join("factory/system/permissions");
fs::create_dir_all(&decisions).map_err(|e| e.to_string())?;
fs::write(decisions.join(m.id.as_str()), &out[..n]).map_err(|e| e.to_string())?;
if decision.granted.contains(Capability::Storage) {
fs::create_dir_all(root.join("data").join(m.id.as_str())).map_err(|e| e.to_string())?;
fs::create_dir_all(root.join("factory/data").join(m.id.as_str())).map_err(|e| e.to_string())?;
}
Ok(())
}