Finding
tls::save_identity writes the QUIC TLS private key with fs::write(key_path, key.secret_der()). On Linux fs::write creates the file with permissions determined by the process umask (commonly 0644), so a default umask of 0022 yields a world-readable private key. The certificate is written with the same call pattern.
Evidence
crates/syndesis/src/tls/mod.rs:107
fs::write(cert_path, &cert_bytes)
crates/syndesis/src/tls/mod.rs:108
fs::write(key_path, key.secret_der())
Neither call sets an explicit file mode, so both inherit the process umask.
Why this matters
When harmonia runs under a non-restrictive umask (the common case for systemd units inheriting the default), any local user or unprivileged app on the device can read the private key file. On a counter-surveillance phone OS this is a key-exfiltration path: a hostile local app reads the TLS identity, and combined with the always-accepting TofuVerifier it can impersonate the device and perform a real-time MitM against renderer connections, defeating transport authentication entirely.
Desired correction
Create the key file with std::fs::OpenOptions using mode(0o600) (via std::os::unix::fs::OpenOptionsExt), or call std::fs::set_permissions to 0600 immediately after writing. The certificate file may remain 0644.
Done when: a test verifies that after save_identity the key file has permissions 0600 regardless of the process umask.
Finding
tls::save_identitywrites the QUIC TLS private key withfs::write(key_path, key.secret_der()). On Linuxfs::writecreates the file with permissions determined by the process umask (commonly 0644), so a default umask of 0022 yields a world-readable private key. The certificate is written with the same call pattern.Evidence
crates/syndesis/src/tls/mod.rs:107crates/syndesis/src/tls/mod.rs:108Neither call sets an explicit file mode, so both inherit the process umask.
Why this matters
When harmonia runs under a non-restrictive umask (the common case for systemd units inheriting the default), any local user or unprivileged app on the device can read the private key file. On a counter-surveillance phone OS this is a key-exfiltration path: a hostile local app reads the TLS identity, and combined with the always-accepting
TofuVerifierit can impersonate the device and perform a real-time MitM against renderer connections, defeating transport authentication entirely.Desired correction
Create the key file with
std::fs::OpenOptionsusingmode(0o600)(viastd::os::unix::fs::OpenOptionsExt), or callstd::fs::set_permissionsto 0600 immediately after writing. The certificate file may remain 0644.Done when: a test verifies that after
save_identitythe key file has permissions 0600 regardless of the process umask.