diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+# v1.0.11.0
+
+## Non-breaking
+
+- Added `connectionNeedsPassword` and `connectionUsedPassword` specs covering trust auth with a `password=` field present in the conninfo (expected `False` for both, since the server never actually challenged for one) and a SCRAM-auth container both with and without a password supplied. Found `pqi-native`'s implementations tracked the conninfo `password=` field instead of libpq's `password_needed` auth-exchange state (`connectionNeedsPassword` was hardcoded `False`; `connectionUsedPassword` was `True` whenever a password string was merely present, trust auth or not).
+
 # v1.0.10.0
 
 ## Non-breaking
diff --git a/pqi-conformance.cabal b/pqi-conformance.cabal
--- a/pqi-conformance.cabal
+++ b/pqi-conformance.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: pqi-conformance
-version: 1.0.10.0
+version: 1.0.11.0
 category: Database, PostgreSQL, Testing
 synopsis: Differential conformance tests for pqi adapters
 description:
diff --git a/src/library/Pqi/Conformance/Operation/ConnectionNeedsPassword.hs b/src/library/Pqi/Conformance/Operation/ConnectionNeedsPassword.hs
--- a/src/library/Pqi/Conformance/Operation/ConnectionNeedsPassword.hs
+++ b/src/library/Pqi/Conformance/Operation/ConnectionNeedsPassword.hs
@@ -1,17 +1,72 @@
--- | Coverage for 'Pqi.connectionNeedsPassword': whether authentication
--- needed a password that was unavailable (False under trust auth).
+-- | Coverage for 'Pqi.connectionNeedsPassword': whether the server actually
+-- challenged for a password during authentication and none was available
+-- (mirroring libpq's @password_needed@ state, not merely whether a
+-- @password=@ field was present in the conninfo).
 module Pqi.Conformance.Operation.ConnectionNeedsPassword
   ( spec,
   )
 where
 
+import Control.Exception (bracket)
+import qualified Data.ByteString.Char8 as ByteString.Char8
+import qualified Data.Text as Text
 import qualified Pqi
 import Pqi.Conformance.Harness
 import Pqi.Conformance.Prelude
+import qualified Pqi.Conformance.Reference as Reference
 import Test.Hspec
+import qualified TestcontainersPostgresql as TcPg
 
 spec :: Pqi.Adapter -> SpecWith ByteString
-spec adapter =
+spec adapter = do
   describe "connectionNeedsPassword" do
-    it "reports whether a password was needed" \conninfo ->
-      differential adapter conninfo Pqi.connectionNeedsPassword
+    it "reports False under trust auth even when a password is supplied" \conninfo ->
+      differential adapter (conninfo <> " password=irrelevant") Pqi.connectionNeedsPassword
+
+    it "reports False once SCRAM authentication succeeded with the right password" \_ ->
+      let scramConfig =
+            TcPg.Config
+              { TcPg.tagName = "postgres:17",
+                TcPg.forwardLogs = False,
+                TcPg.auth = TcPg.CredentialsAuth "scram" "secret"
+              }
+       in TcPg.run scramConfig \(host, port) -> do
+            let conninfo = scramConninfo host port "secret"
+            candidate <- bracket (Pqi.connectdb adapter conninfo) Pqi.finish Pqi.connectionNeedsPassword
+            reference <- bracket (Pqi.connectdb Reference.adapter conninfo) Pqi.finish Pqi.connectionNeedsPassword
+            candidate `shouldBe` reference
+
+    it "reports True when SCRAM authentication is challenged for but no password was supplied" \_ ->
+      let scramConfig =
+            TcPg.Config
+              { TcPg.tagName = "postgres:17",
+                TcPg.forwardLogs = False,
+                TcPg.auth = TcPg.CredentialsAuth "scram" "secret"
+              }
+       in TcPg.run scramConfig \(host, port) -> do
+            let conninfo = scramConninfoNoPassword host port
+            candidate <- bracket (Pqi.connectdb adapter conninfo) Pqi.finish Pqi.connectionNeedsPassword
+            reference <- bracket (Pqi.connectdb Reference.adapter conninfo) Pqi.finish Pqi.connectionNeedsPassword
+            candidate `shouldBe` reference
+
+scramConninfo :: Text -> Word16 -> ByteString -> ByteString
+scramConninfo host port password =
+  ByteString.Char8.pack
+    ( "host="
+        <> Text.unpack host
+        <> " port="
+        <> show port
+        <> " user=scram password="
+        <> ByteString.Char8.unpack password
+        <> " dbname=scram"
+    )
+
+scramConninfoNoPassword :: Text -> Word16 -> ByteString
+scramConninfoNoPassword host port =
+  ByteString.Char8.pack
+    ( "host="
+        <> Text.unpack host
+        <> " port="
+        <> show port
+        <> " user=scram dbname=scram"
+    )
diff --git a/src/library/Pqi/Conformance/Operation/ConnectionUsedPassword.hs b/src/library/Pqi/Conformance/Operation/ConnectionUsedPassword.hs
--- a/src/library/Pqi/Conformance/Operation/ConnectionUsedPassword.hs
+++ b/src/library/Pqi/Conformance/Operation/ConnectionUsedPassword.hs
@@ -1,17 +1,47 @@
--- | Coverage for 'Pqi.connectionUsedPassword': whether authentication
--- used a password (False under trust auth).
+-- | Coverage for 'Pqi.connectionUsedPassword': whether the server actually
+-- challenged for a password during authentication (mirroring libpq's
+-- @password_needed@ state, not merely whether a @password=@ field was
+-- present in the conninfo).
 module Pqi.Conformance.Operation.ConnectionUsedPassword
   ( spec,
   )
 where
 
+import Control.Exception (bracket)
+import qualified Data.ByteString.Char8 as ByteString.Char8
+import qualified Data.Text as Text
 import qualified Pqi
 import Pqi.Conformance.Harness
 import Pqi.Conformance.Prelude
+import qualified Pqi.Conformance.Reference as Reference
 import Test.Hspec
+import qualified TestcontainersPostgresql as TcPg
 
 spec :: Pqi.Adapter -> SpecWith ByteString
-spec adapter =
+spec adapter = do
   describe "connectionUsedPassword" do
-    it "reports whether a password was used" \conninfo ->
-      differential adapter conninfo Pqi.connectionUsedPassword
+    it "reports False under trust auth even when a password is supplied" \conninfo ->
+      differential adapter (conninfo <> " password=irrelevant") Pqi.connectionUsedPassword
+
+    it "reports True once SCRAM authentication was actually challenged for" \_ ->
+      let scramConfig =
+            TcPg.Config
+              { TcPg.tagName = "postgres:17",
+                TcPg.forwardLogs = False,
+                TcPg.auth = TcPg.CredentialsAuth "scram" "secret"
+              }
+       in TcPg.run scramConfig \(host, port) -> do
+            let conninfo = scramConninfo host port
+            candidate <- bracket (Pqi.connectdb adapter conninfo) Pqi.finish Pqi.connectionUsedPassword
+            reference <- bracket (Pqi.connectdb Reference.adapter conninfo) Pqi.finish Pqi.connectionUsedPassword
+            candidate `shouldBe` reference
+
+scramConninfo :: Text -> Word16 -> ByteString
+scramConninfo host port =
+  ByteString.Char8.pack
+    ( "host="
+        <> Text.unpack host
+        <> " port="
+        <> show port
+        <> " user=scram password=secret dbname=scram"
+    )
