commit b3d711918feb60f2179fc9bfcad36616102aebed
Author: Ben Sima <ben@bensima.com>
Date: Thu Jan 1 14:11:01 2026
Add ReadWritePaths to Hardening schema (t-317)
Added hardeningReadWritePaths :: [Text] field to Hardening type.
Updated Systemd.hs to combine DATA_DIR and readWritePaths into
a single ReadWritePaths directive.
This fixes Ava not being able to write to /var/lib/omni/tasks.db
when ProtectSystem=strict is enabled.
Task-Id: t-317
diff --git a/Omni/Deploy/Manifest.hs b/Omni/Deploy/Manifest.hs
index 532ec4c0..ea99d2c1 100644
--- a/Omni/Deploy/Manifest.hs
+++ b/Omni/Deploy/Manifest.hs
@@ -180,7 +180,8 @@ data Hardening = Hardening
{ hardeningDynamicUser :: Bool,
hardeningPrivateTmp :: Bool,
hardeningProtectSystem :: Text,
- hardeningProtectHome :: Bool
+ hardeningProtectHome :: Bool,
+ hardeningReadWritePaths :: [Text]
}
deriving (Show, Eq, Generic)
@@ -198,6 +199,9 @@ instance Aeson.FromJSON Hardening where
<*> o
.:? "protectHome"
.!= True
+ <*> o
+ .:? "readWritePaths"
+ .!= []
instance Aeson.ToJSON Hardening where
toJSON Hardening {..} =
@@ -205,11 +209,12 @@ instance Aeson.ToJSON Hardening where
[ "dynamicUser" .= hardeningDynamicUser,
"privateTmp" .= hardeningPrivateTmp,
"protectSystem" .= hardeningProtectSystem,
- "protectHome" .= hardeningProtectHome
+ "protectHome" .= hardeningProtectHome,
+ "readWritePaths" .= hardeningReadWritePaths
]
defaultHardening :: Hardening
-defaultHardening = Hardening False True "strict" True
+defaultHardening = Hardening False True "strict" True []
data Service = Service
{ serviceName :: Text,
diff --git a/Omni/Deploy/Systemd.hs b/Omni/Deploy/Systemd.hs
index 99d48200..8d1f28b3 100644
--- a/Omni/Deploy/Systemd.hs
+++ b/Omni/Deploy/Systemd.hs
@@ -106,9 +106,14 @@ generateUnit Service {..} =
++ readWritePathsLine
readWritePathsLine =
- case Map.lookup "DATA_DIR" serviceEnv of
- Just dataDir -> ["ReadWritePaths=" <> dataDir]
- Nothing -> []
+ let dataDirPaths = case Map.lookup "DATA_DIR" serviceEnv of
+ Just dataDir -> [dataDir]
+ Nothing -> []
+ hardeningPaths = hardeningReadWritePaths serviceHardening
+ allPaths = dataDirPaths ++ hardeningPaths
+ in if null allPaths
+ then []
+ else ["ReadWritePaths=" <> Text.intercalate " " allPaths]
installSection =
[ "",
@@ -222,7 +227,7 @@ mkTestService name path =
serviceEnvFile = Nothing,
serviceHttp = Nothing,
serviceSystemd = Systemd ["network-online.target"] [] "on-failure" 5,
- serviceHardening = Hardening False True "strict" True,
+ serviceHardening = Hardening False True "strict" True [],
serviceRevision = Nothing
}
@@ -292,7 +297,7 @@ test_generateUnitWithHardening =
Test.unit "generates unit with hardening" <| do
let svc =
(mkTestService "hardened" "/nix/store/abc")
- { serviceHardening = Hardening False True "full" True
+ { serviceHardening = Hardening False True "full" True []
}
unit = generateUnit svc
Text.isInfixOf "PrivateTmp=yes" unit Test.@=? True