Haskell SDK
The Haskell SDK (secretspec-hs) is a thin client over the secretspec-ffi C
ABI, linked at build time via the Haskell FFI. Resolution happens in the Rust
core, so the SDK inherits every provider with no Haskell-side logic.
Quick start
Section titled “Quick start”import qualified SecretSpec as Simport qualified Data.Map.Strict as Mapimport Data.Function ((&))
main :: IO ()main = do resolved <- S.load ( S.builder & S.withProvider "keyring://" & S.withProfile "production" & S.withReason "boot web app" )
print (S.resolvedProvider resolved, S.resolvedProfile resolved) case Map.lookup "DATABASE_URL" (S.resolvedSecrets resolved) of Just db -> print (S.get db) -- the value, or the file path for as_path secrets Nothing -> pure () S.setAsEnv resolved -- export everything into the process environmentA missing required secret throws MissingRequiredError; any other failure
throws SecretSpecError (with a stable errorKind).
as_path secrets are materialized to temp files that outlive the call; call
S.close resolved when done so they do not accumulate in the temp dir.
Value-free report
Section titled “Value-free report”S.report returns the inventory/preflight view: per-secret status and
provenance, never a value. Unlike load, it does not throw when a required
secret is missing — that secret appears as a SecretReport with srStatus
"missing_required".
rep <- S.report (S.builder & S.withProfile "production")mapM_ (\s -> print (S.srName s, S.srStatus s, S.srRequired s)) (S.reportSecrets rep)Typed access (codegen)
Section titled “Typed access (codegen)”Generate a typed record with secretspec schema plus
quicktype, then decode S.fieldsJson resolved:
secretspec schema | quicktype -s schema --top-level SecretSpec --lang haskell -o Secrets.hsBuilding
Section titled “Building”The native secretspec-ffi library is linked at build time, so point cabal at
the built cdylib and put the same directory on the runtime loader path:
cargo build -p secretspec-ffiTARGET="$(cargo metadata --no-deps --format-version 1 \ | grep -o '"target_directory":"[^"]*"' | head -1 | sed 's/.*:"\(.*\)"/\1/')"cabal build --extra-lib-dirs="$TARGET/debug"LD_LIBRARY_PATH="$TARGET/debug" cabal test --extra-lib-dirs="$TARGET/debug"