diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
 # Changelog
 
+## [0.6.0.1] - 2024-10-18
+
+### Added
+
+* `secretTextFileSetting`
+* `secretTextFileOrBareSetting`
+
 ## [0.6.0.0] - 2024-10-18
 
 ### Added
diff --git a/opt-env-conf.cabal b/opt-env-conf.cabal
--- a/opt-env-conf.cabal
+++ b/opt-env-conf.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           opt-env-conf
-version:        0.6.0.0
+version:        0.6.0.1
 synopsis:       Settings parsing for Haskell: command-line arguments, environment variables, and configuration values.
 homepage:       https://github.com/NorfairKing/opt-env-conf#readme
 bug-reports:    https://github.com/NorfairKing/opt-env-conf/issues
diff --git a/src/OptEnvConf.hs b/src/OptEnvConf.hs
--- a/src/OptEnvConf.hs
+++ b/src/OptEnvConf.hs
@@ -99,6 +99,8 @@
 
     -- *** Secrets
     readSecretTextFile,
+    secretTextFileSetting,
+    secretTextFileOrBareSetting,
 
     -- *** Migration
     strOption,
diff --git a/src/OptEnvConf/Parser.hs b/src/OptEnvConf/Parser.hs
--- a/src/OptEnvConf/Parser.hs
+++ b/src/OptEnvConf/Parser.hs
@@ -52,6 +52,8 @@
     yesNoSwitch,
     makeDoubleSwitch,
     readSecretTextFile,
+    secretTextFileSetting,
+    secretTextFileOrBareSetting,
 
     -- * Parser implementation
     Parser (..),
@@ -911,6 +913,73 @@
 -- that messes with line endings.
 readSecretTextFile :: Path Abs File -> IO Text
 readSecretTextFile = fmap T.strip . T.readFile . fromAbsFile
+
+-- | Load a secret from a text file, with 'readSecretTextFile'
+secretTextFileSetting :: (HasCallStack) => [Builder FilePath] -> Parser Text
+secretTextFileSetting bs = withFrozenCallStack $ mapIO readSecretTextFile $ filePathSetting bs
+
+-- | Load a secret from a text file, with 'readSecretTextFile', or specify it
+-- directly
+secretTextFileOrBareSetting :: (HasCallStack) => [Builder FilePath] -> Parser Text
+secretTextFileOrBareSetting bs =
+  withFrozenCallStack $
+    let b = mconcat $ bs ++ [reader str]
+        bareSetting f = T.pack <$> setting [mapMaybeBuilder f b, metavar "SECRET"]
+        fileSetting f = secretTextFileSetting [mapMaybeBuilder f b]
+     in choice
+          [ bareSetting $ \case
+              BuildTryArgument -> Nothing
+              BuildAddShort s -> Just $ BuildAddShort s
+              BuildAddLong l -> Just $ BuildAddLong l
+              BuildAddEnv _ -> Nothing
+              BuildAddConf _ -> Nothing
+              BuildSetDefault _ _ -> Nothing
+              i -> Just i,
+            fileSetting $ \case
+              BuildTryArgument -> Nothing
+              BuildAddShort _ -> Nothing
+              BuildAddLong l -> Just $ BuildAddLong (l <> NE.fromList "-file")
+              BuildAddEnv _ -> Nothing
+              BuildAddConf _ -> Nothing
+              BuildSetDefault _ _ -> Nothing
+              i -> Just i,
+            bareSetting $ \case
+              BuildTryArgument -> Nothing
+              BuildTryOption -> Nothing
+              BuildAddShort _ -> Nothing
+              BuildAddLong _ -> Nothing
+              BuildAddEnv v -> Just $ BuildAddEnv v
+              BuildAddConf _ -> Nothing
+              BuildSetDefault _ _ -> Nothing
+              i -> Just i,
+            fileSetting $ \case
+              BuildTryArgument -> Nothing
+              BuildTryOption -> Nothing
+              BuildAddShort _ -> Nothing
+              BuildAddLong _ -> Nothing
+              BuildAddEnv e -> Just $ BuildAddEnv $ e ++ "_FILE"
+              BuildAddConf _ -> Nothing
+              BuildSetDefault _ _ -> Nothing
+              i -> Just i,
+            bareSetting $ \case
+              BuildTryArgument -> Nothing
+              BuildTryOption -> Nothing
+              BuildAddShort _ -> Nothing
+              BuildAddLong _ -> Nothing
+              BuildAddEnv _ -> Nothing
+              BuildAddConf k -> Just $ BuildAddConf k
+              BuildSetDefault _ _ -> Nothing
+              i -> Just i,
+            fileSetting $ \case
+              BuildTryArgument -> Nothing
+              BuildTryOption -> Nothing
+              BuildAddShort _ -> Nothing
+              BuildAddLong _ -> Nothing
+              BuildAddEnv _ -> Nothing
+              BuildAddConf k -> Just $ BuildAddConf $ suffixConfigValSettingKey "-file" k
+              BuildSetDefault _ _ -> Nothing
+              i -> Just i
+          ]
 
 -- | Prefix all 'long's and 'short's with a given 'String'.
 {-# ANN subArgs ("NOCOVER" :: String) #-}
diff --git a/src/OptEnvConf/Setting.hs b/src/OptEnvConf/Setting.hs
--- a/src/OptEnvConf/Setting.hs
+++ b/src/OptEnvConf/Setting.hs
@@ -35,10 +35,12 @@
     -- * Internal
     showSettingABit,
     completeBuilder,
+    mapMaybeBuilder,
     emptySetting,
     Metavar,
     Help,
     prefixConfigValSetting,
+    suffixConfigValSettingKey,
   )
 where
 
@@ -96,6 +98,14 @@
 prefixConfigValSetting :: String -> ConfigValSetting a -> ConfigValSetting a
 prefixConfigValSetting prefix c = c {configValSettingPath = prefix NE.<| configValSettingPath c}
 
+suffixConfigValSettingKey :: String -> ConfigValSetting a -> ConfigValSetting a
+suffixConfigValSettingKey suffix c = c {configValSettingPath = suffixPath $ configValSettingPath c}
+  where
+    suffixPath :: NonEmpty String -> NonEmpty String
+    suffixPath (f :| rest) = case NE.nonEmpty rest of
+      Nothing -> (f <> suffix) :| []
+      Just ne -> f NE.<| suffixPath ne
+
 -- | A 'mempty' 'Setting' to build up a setting from.
 emptySetting :: Setting a
 emptySetting =
@@ -204,6 +214,9 @@
 -- | Complete a 'Builder' into a 'Setting'
 completeBuilder :: Builder a -> Setting a
 completeBuilder b = applyBuildInstructions (unBuilder b) emptySetting
+
+mapMaybeBuilder :: (BuildInstruction a -> Maybe (BuildInstruction b)) -> Builder a -> Builder b
+mapMaybeBuilder func = Builder . mapMaybe func . unBuilder
 
 -- | Document a setting
 --
