diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,15 @@
 
 ## [Unreleased]
 
+## 0.17.0.0 — 2026-09-17
+
+### New Features
+
+- Add `withFreshResourceStorePrepared`, which clones a database, runs a
+  privileged preparation callback against a temporary store for roles and
+  ACLs, closes it, and then opens the resource-aware application store with
+  modified connection settings.
+
 ## 0.16.0.0 — 2026-09-07
 
 ### Other Changes
diff --git a/keiro-test-support.cabal b/keiro-test-support.cabal
--- a/keiro-test-support.cabal
+++ b/keiro-test-support.cabal
@@ -1,37 +1,42 @@
-cabal-version:   3.0
-name:            keiro-test-support
-version:         0.16.0.0
-synopsis:        Shared PostgreSQL test fixtures for Keiro test suites
+cabal-version: 3.0
+name: keiro-test-support
+version: 0.17.0.0
+synopsis: Shared PostgreSQL test fixtures for Keiro test suites
 description:
   Suite-level ephemeral-PostgreSQL fixtures shared by the Keiro test
   suites. Implements the ephemeral-pg template-database pattern: one cached
   server per suite, one migrated template database, and a clean cloned
   database per example.
 
-license:         BSD-3-Clause
-license-file:    LICENSE
-author:          Nadeem Bitar
-maintainer:      nadeem@gmail.com
-copyright:       2026 Nadeem Bitar
-category:        Testing
-homepage:        https://github.com/shinzui/keiro#readme
-bug-reports:     https://github.com/shinzui/keiro/issues
-build-type:      Simple
+license: BSD-3-Clause
+license-file: LICENSE
+author: Nadeem Bitar
+maintainer: nadeem@gmail.com
+copyright: 2026 Nadeem Bitar
+category: Testing
+homepage: https://github.com/shinzui/keiro#readme
+bug-reports: https://github.com/shinzui/keiro/issues
+build-type: Simple
 extra-doc-files: CHANGELOG.md
-tested-with:     GHC >=9.12 && <9.13
+tested-with: ghc >=9.12 && <9.13
 
 source-repository head
-  type:     git
+  type: git
   location: https://github.com/shinzui/keiro.git
 
 common warnings
   ghc-options:
-    -Wall -Wcompat -Widentities -Wincomplete-record-updates
-    -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints
+    -Wall
+    -Wcompat
+    -Widentities
+    -Wincomplete-record-updates
+    -Wincomplete-uni-patterns
+    -Wpartial-fields
+    -Wredundant-constraints
 
 library
-  import:             warnings
-  default-language:   GHC2024
+  import: warnings
+  default-language: GHC2024
   default-extensions:
     BlockArguments
     ImportQualifiedPost
@@ -39,19 +44,19 @@
     OverloadedRecordDot
     OverloadedStrings
 
-  exposed-modules:    Keiro.Test.Postgres
-  hs-source-dirs:     src
+  exposed-modules: Keiro.Test.Postgres
+  hs-source-dirs: src
   build-depends:
-    , aeson                    >=2.2       && <2.3
-    , base                     >=4.21      && <5
-    , containers               >=0.6       && <0.8
-    , effectful                >=2.6       && <2.7
-    , ephemeral-pg             >=0.2       && <0.3
-    , hasql                    >=1.10      && <1.11
-    , hasql-pool               >=1.2       && <1.5
-    , keiro-migrations         ^>=0.16.0.0
-    , kiroku-store             >=0.8       && <0.9
-    , kiroku-store-migrations  ^>=0.4.0.0
-    , pg-migrate               ^>=1.1.0.0
-    , stm                      >=2.5       && <2.6
-    , text                     >=2.1       && <2.2
+    aeson >=2.2 && <2.3,
+    base >=4.21 && <5,
+    containers >=0.6 && <0.8,
+    effectful >=2.6 && <2.7,
+    ephemeral-pg >=0.2 && <0.3,
+    hasql >=1.10 && <1.11,
+    hasql-pool >=1.2 && <1.5,
+    keiro-migrations ^>=0.17.0.0,
+    kiroku-store >=0.8 && <0.9,
+    kiroku-store-migrations ^>=0.4.0.0,
+    pg-migrate ^>=1.1.0.0,
+    stm >=2.5 && <2.6,
+    text >=2.1 && <2.2,
diff --git a/src/Keiro/Test/Postgres.hs b/src/Keiro/Test/Postgres.hs
--- a/src/Keiro/Test/Postgres.hs
+++ b/src/Keiro/Test/Postgres.hs
@@ -31,6 +31,7 @@
     StoreRunner (..),
     withFreshResourceStore,
     withFreshResourceStoreWith,
+    withFreshResourceStorePrepared,
     withFreshStores2,
   )
 where
@@ -148,14 +149,35 @@
   IO ()
 withFreshResourceStoreWith fixture modify action =
   withFreshDatabase fixture \connStr ->
-    runEff $
-      withKirokuStore (modify (Store.defaultConnectionSettings connStr)) $ do
-        store <- getKirokuStore
-        withEffToIO (ConcUnlift Persistent Unlimited) \unlift ->
-          action
-            ( store,
-              StoreRunner (unlift . runErrorNoCallStack . runStoreResource)
-            )
+    runResourceStore (modify (Store.defaultConnectionSettings connStr)) action
+
+-- | Clone a database, let a privileged store prepare database roles or ACLs,
+-- then open the resource-aware store with modified application settings.
+-- The preparation store is closed before the application store is opened.
+withFreshResourceStorePrepared ::
+  Fixture ->
+  (Store.KirokuStore -> IO ()) ->
+  (Store.ConnectionSettings -> Store.ConnectionSettings) ->
+  ((Store.KirokuStore, StoreRunner) -> IO ()) ->
+  IO ()
+withFreshResourceStorePrepared fixture prepare modify action =
+  withFreshDatabase fixture \connStr -> do
+    Store.withStore (Store.defaultConnectionSettings connStr) prepare
+    runResourceStore (modify (Store.defaultConnectionSettings connStr)) action
+
+runResourceStore ::
+  Store.ConnectionSettings ->
+  ((Store.KirokuStore, StoreRunner) -> IO ()) ->
+  IO ()
+runResourceStore settings action =
+  runEff $
+    withKirokuStore settings $ do
+      store <- getKirokuStore
+      withEffToIO (ConcUnlift Persistent Unlimited) \unlift ->
+        action
+          ( store,
+            StoreRunner (unlift . runErrorNoCallStack . runStoreResource)
+          )
 
 -- | Like 'withFreshStore' but provides two independent migrated databases (and
 -- two stores) cloned from the same template — used by cross-context
