fix(server): restrict SQLite database file permissions to 0o600#1359
Merged
TaylorMutch merged 1 commit intoMay 13, 2026
Conversation
c41be50 to
61bcf0d
Compare
Signed-off-by: Adrien Langou <alangou@nvidia.com>
61bcf0d to
748f712
Compare
|
Label |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The gateway SQLite database stores provider API keys, SSH session tokens, and sandbox metadata, but SQLite was creating it with
0o644 & ~umask— readable by other local users on shared hosts. This PR tightens the on-disk mode to0o600immediately after the pool is connected, and applies the same hardening to the<db>-waland<db>-shmsidecars when SQLite is in WAL mode. Satisfies FSR-029 (mitigates T-038).Related Issue
Closes OS-79
Changes
crates/openshell-server/src/persistence/sqlite.rs:connect_withconsumes the options, then tighten permissions to0o600once the pool is up. The hardening is reapplied on every connect so pre-existing databases from older gateway versions are also locked down. In-memory databases (:memory:/mode=memory) are skipped.openshell_core::paths::set_file_owner_onlyhelper (single source of truth, alreadycfg(unix)-gated and used by the bootstrap and certgen modules) rather than reimplementingstd::fs::set_permissions(..., 0o600).<db>-wal(write-ahead log) and<db>-shm(shared memory index) sidecars when present. They mirror the same sensitive payload as the main file and are created automatically when the gateway runs SQLite in WAL mode. A smallsqlite_sidecar_pathshelper derives the sidecar paths the same way SQLite does.crates/openshell-server/src/persistence/tests.rs: fivecfg(unix)tests covering the hardening at increasing levels of fidelity:sqlite_connect_restricts_db_file_permissions— fresh DB created viaStore::connectends up at0o600.sqlite_connect_tightens_existing_db_file_permissions— pre-existing DB at0o644(older gateway version) is re-tightened on reconnect.restrict_db_file_permissions_tightens_main_and_wal_and_shm_files— synthetic main + WAL + SHM files at0o644are all tightened to0o600(proves the chmod loop walks all three paths).restrict_db_file_permissions_skips_missing_sidecars— theexists()guard avoids errors when no WAL/SHM sidecar is present (the current production path; sqlx 0.8 does not default to WAL and does not parsejournal_modefrom the URL).restrict_db_file_permissions_handles_real_sqlite_wal_files— opens a real sqlx pool withSqliteJournalMode::Walvia the builder API, forces a write so SQLite materializes the WAL on disk, loosens permissions, then verifies the helper tightens the main DB plus both real sqlite-managed sidecars back to0o600.architecture/gateway.md: updated the Persistence section to document the on-disk mode invariant for both the main DB file and the<db>-wal/<db>-shmsidecars.Testing
mise run pre-commitpasses (cargo fmt,clippy -D warnings, license headers)#[cfg(unix)]tests listed above; fullpersistence::suite (38 tests) greene2e/Manual verification matches the issue's acceptance criterion:
ls -la <db>*shows-rw-------for the database and any WAL/SHM sidecars after the gateway connects.Checklist