Introduction
PostgreSQL supports multiple client authentication methods. In addition to external authentication providers, it also supports password-based authentication using credentials stored in the database.
Among the password-based methods, the recommended one is scram-sha-256, which is a form of SCRAM authentication as discussed in the previous article.
This article introduces how SCRAM authentication works in PostgreSQL, and explains a new feature planned for PostgreSQL 18: SCRAM pass-through authentication.
2025-05-31 Added usage of SCRAM pass-through authentication
(This article is a translation of a Japanese article written by the author themselves.)
Using SCRAM Authentication in PostgreSQL
SCRAM authentication is triggered in PostgreSQL when all of the following conditions are met:
- The password for the user is stored in 
scram-sha-256format, - The user has registered a password (credential) in the database, and
 - The authentication method selected in 
pg_hba.confis eitherscram-sha-256ormd5*1. 
Password Storage Format
Database user passwords are stored in the rolpassword column of the system catalog pg_authid.
When the password_encryption parameter is set to scram-sha-256, the value follows this format as described in the documentation and defined in RFC 5803:
SCRAM-SHA-256$<iteration count>:<salt>$<StoredKey>:<ServerKey>
Here, iteration count, salt, StoredKey, and ServerKey correspond to the values used in the SCRAM computation flow illustrated below:

Diagram: Computation flow in SCRAM authentication
Diagram: SCRAM authentication computation flow
Password Registration
Passwords are registered in PostgreSQL using the PASSWORD clause of the CREATE ROLE or ALTER ROLE command.
For example:
CREATE ROLE yourname ... PASSWORD 'yourpassword';
This sends the plaintext password to the server, where StoredKey and ServerKey are computed.
To avoid sending the plaintext password to the server, you can directly specify the SCRAM format string (as defined in RFC 5803) in the PASSWORD clause*2.
PostgreSQL tools provide client-side computation methods:
- 
PQencryptPasswordConnfunction in libpq (documentation) - 
\passwordmeta-command in psql (documentation) 
Some PostgreSQL variants enforce password policies (e.g., complexity or reuse restrictions) on the server side.
However, if the password is hashed on the client and never sent in plaintext, the server cannot enforce such policies. In such cases, it is the user's responsibility to ensure compliance.
Authentication
The actual authentication method is determined by the server.
If the server selects password authentication, the plaintext password is sent.
To prevent this, the client can set the require_auth connection parameter explicitly to scram-sha-256 (documentation) to force SCRAM authentication.
What is SCRAM Pass-Through Authentication?
SCRAM pass-through authentication takes advantage of the SCRAM property discussed in the previous article: during a successful authentication session, the server obtains ClientKey, which is a credential equivalent to the user's password.
Using ClientKey, the server can generate ClientSignature and ClientProof, and authenticate itself to another server that shares the same credentials—effectively impersonating the user.
SCRAM Pass-Through Authentication in PostgreSQL
The following commit was added to the PostgreSQL master branch (REL_18_BETA1):
postgres_fdw: SCRAM authentication pass-through
This enables SCRAM authentication for postgres_fdw when connecting to
a foreign server without having to store a plain-text password on user
mapping options.This is done by saving the SCRAM ClientKey and ServerKey from the
client authentication and using those instead of the plain-text
password for the server-side SCRAM exchange. The new foreign-server
or user-mapping option "use_scram_passthrough" enables this.
According to the PostgreSQL 18 Beta documentation, when using postgres_fdw, if both the source and target servers share the same credentials and the user authenticates to the source with scram-sha-256, the source server can use the recovered ClientKey to authenticate to the target. This eliminates the need to store plain-text passwords in the pg_user_mapping system catalog.
To support this, a new libpq connection parameter scram_client_key has been introduced*3.
  
  
  Using SCRAM Pass-Through Authentication in postgresql_fdw
Setting Passwords for Remote Server Users
When using SCRAM pass-through authentication, the credentials of the source and destination servers must be exactly the same, including salt and other information. Refer to the credentials of the source server from the pg_authid system catalog and specify them directly in the PASSWORD clause as the password for the user on the destination server.
# Referencing credentials of the source server
SELECT rolpassword FROM pg_authid WHERE rolname = 'test'
                                    rolpassword
--------------------------------------------------------------------------
 SCRAM-SHA-256$4096:test-salt$test-stored-key:test-server-key
(1 row)
# Change credentials of server to connect to (requires administrator privileges)
ALTER ROLE test PASSWORD 'SCRAM-SHA-256$4096:test-salt$test-stored-key:test-server-key'
Creating User Mappings
When creating a user mapping to an external server, use the use_scram_passthrough option instead of the password option.
# PostgreSQL 17 and earlier
 CREATE USER MAPING FOR test SERVER server2 OPTIONS (user 'test', password 'testpassword');
# PostgreSQL 18
 CREATE USER MAPING FOR test SERVER server2 OPTIONS (user 'test', use_scram_passthrough 'true');
Connect to the source server
Connect to the source PostgreSQL server; since SCRAM pass-through authentication only passes credentials, the source server must be logged in with SCRAM authentication.
  
  
  Storage and Use of ClientKey in Pass-Through Authentication
In PostgreSQL, SCRAM authentication message exchanges are handled in the scram_exchange function in src/backend/libpq/auth-scram.c.
As of May 25, 2025, the master branch unconditionally copies ClientKey into the global MyProcPort structure upon successful authentication (source).
This information continues to be maintained during the lifetime of the backend process associated with the connection.
In postgres_fdw, if the MyProcPort structure contains the SCRAM keys and use_scram_passthrough is enabled, those keys are added to the connection parameters (source).
Conclusion
The previous article explained how a server can reconstruct ClientKey during SCRAM authentication, and how this enables transparent login to another server in the same credential-sharing cluster. PostgreSQL’s SCRAM pass-through authentication is a direct application of this property.
Although this feature must be explicitly enabled, it seems intended not for security reasons, but to give administrators control over the chosen authentication method.
Even in environments where postgres_fdw is not used, ClientKey is unconditionally retained in memory after a SCRAM login. The MyProcPort structure where the data is saved is a global variable, and is an area that can be easily referenced if extension modules or user-defined functions to be added to the PostgreSQL server are implemented in C language (or its wrapper).
Thus, DBAs must continue to verify the trustworthiness of any added modules.
Personally I feel more at ease when I can choose not to keep the ClientKey in memory.
Footnotes
*1: Even if the method is md5, SCRAM authentication will be used if the password is stored in SCRAM format, for compatibility reasons.
*2: This means that PostgreSQL does not transparently accept any arbitrary password format.
*3: A corresponding scram_server_key parameter is also added for server authentication.
    
Top comments (0)