PostgreSQL: MD5 password support is deprecated – updating the user passwords

Eight years ago, PostgreSQL introduced scram-sha-256 hashes for passwords.

Eleven months ago, MD5 was deprecated.

Yesterday, I got caught up with all this.

Some of this post will deal with how I fixed it, but mostly it is documenting (for myself) what I did. The fix covers several services and takes place over multiple days.

First, some background on why this change has come into focus for me.

I have a FreeBSD jail dedicated to testing database backups. It takes each backup and restores it. That host is known as dbclone. It both receives the backups and does the test restores, reporting any errors. My theory being: the usefulness of a backup is gone if it cannot be restored.

dbclone was updated to PostgreSQL 18.0 yesterday (my primary development server has been using PostgreSQL 18.b1 since Fri Aug 8 13:40:52 2025 UTC; that’s from the installation date of the package).

As part of the testing process, dbclone erases the PGDATA directory (in my case: /var/db/postgres/data18) and runs initdb before each test. This way, a fresh start is promised to each test.

The first task of testing is to set up the required users. I take that from the globals dump (see the –globals-only
option on pg_dumpall. My backups dump the globals into a file named globals.sql.

Yesterday I started getting these messages:

Nov  1 13:15:29 dbclone postgres[90215]: [8-1] 2025-11-01 13:15:29.630 UTC [90215] WARNING:  setting an MD5-encrypted password
Nov  1 13:15:29 dbclone postgres[90215]: [8-2] 2025-11-01 13:15:29.630 UTC [90215] DETAIL:  MD5 password support is deprecated and will be removed in a future release of PostgreSQL.
Nov  1 13:15:29 dbclone postgres[90215]: [8-3] 2025-11-01 13:15:29.630 UTC [90215] HINT:  Refer to the PostgreSQL documentation for details about migrating to another password type.

A short search found the commit in question.

In short, it says: MD5 has been considered unsuitable for use as a cryptographic hash algorithm for some time. Let’s deprecate it.

The Miscellaneous Functions documentationsupport says “scram-sha-256 was introduced in PostgreSQL version 10”. Good news. The oldest PostgreSQL version I have here is 16 – I could have done this conversion back in 2017 (just over 8 years ago now). However, it also means I can implement it now on all my systems.

Suppression

The warnings can be disabled by setting the md5_password_warnings parameter to off. I’ve decided not to do that on my systems.

What users?

I think the first order of business is: what users are affected? I’ll need to know what users I need to have their passwords reset. In my case, none of those users are people; it’s all code.

The passwords are stored as hashes. The hashing algorithm used (at the time the password is set) is determined by the configuration item password_encryption. Changing the password encryption authentication method does not affect already stored passwords. The change will affect only future password assignments.

My plan:

  1. compile the user of users
  2. make sure I have a script to set the passwords
  3. change password_encryption
  4. reset all the passwords
  5. modify pg_hba.conf
  6. test
  7. repeat on other servers

Compile the user of users

[13:08 pg03 dvl ~] % psql -U postgres postgres psql (16.10) Type “help” for help. postgres=# select * from pg_shadow where usename = ‘dvl’; usename | usesysid | usecreatedb | usesuper | userepl | usebypassrls | passwd | valuntil | useconfig ———+———-+————-+———-+———+————–+————————————-+———-+———– dvl | 16399 | t | t | f | f | md5d4c2b11015800cd379b5d26d0dba71bc | | (1 row)

See below where I used pg_authid instead. That works with NOLOGIN users.

In the passwd column is the hash of my actual password – and no, that’s not the actual hash. What you see is something I made up.

If you need a full list of the users:

postgres=# SELECT usename                                
FROM pg_shadow
WHERE passwd LIKE 'md5%' order by usename;
        usename        
-----------------------
john
michael
david
chris
mike
james
mark
jason
robert
jessica
sarah
jennifer
paul
brian
kevin
daniel
ryan
matt
andrew
michelle
steve
lisa
alex
joe
amanda
ashley
scott
richard
eric
jeff
justin
karen
linda
mary
adam
melissa
matthew
nick
stephanie
anthony
tom
josh
laura
(43 rows)

postgres=# 

As for the password hash above, those are not actual user names from my system. I took them from https://github.com/insidetrust/statistically-likely-usernames/blob/master/john.txt

I also found it interesting that I had several users who didn’t have MD5 passwords. I found them using this query:

SELECT usename                                                     
FROM pg_shadow
WHERE passwd NOT LIKE 'md5%' order by usename;

I thought to check for that after I found this entry:

[15:58 pg03 dvl ~] % sudo grep password_encryption /var/db/postgres/data16/postgresql.conf
#password_encryption = scram-sha-256	# scram-sha-256 or md5

I checked the host itself:

freshports.dev=# show password_encryption;
 password_encryption 
---------------------
 scram-sha-256
(1 row)

That made me realize: scram-sha-256 has been the default for some time. It also made me realize I don’t need to modify password_encryption – it’s already the default.

However, I did test that theory on a PostgreSQL 16 host:

[16:11 pg03 dvl ~] % psql postgres
psql (16.10)
Type "help" for help.

postgres=# drop role deleteme;
DROP ROLE
postgres=# create role deleteme with password 'testing';
CREATE ROLE
postgres=# select * from pg_shadow where usename = 'deleteme';
 usename | usesysid | usecreatedb | usesuper | userepl | usebypassrls | passwd | valuntil | useconfig 
---------+----------+-------------+----------+---------+--------------+--------+----------+-----------
(0 rows)

postgres=# alter role deleteme login;
ALTER ROLE
postgres=# select * from pg_shadow where usename = 'deleteme';
 usename  | usesysid | usecreatedb | usesuper | userepl | usebypassrls |                                                                passwd                                                                 | valuntil | useconfig 
----------+----------+-------------+----------+---------+--------------+---------------------------------------------------------------------------------------------------------------------------------------+----------+-----------
 deleteme |  2062883 | f           | f        | f       | f            | SCRAM-SHA-256$4096:DmdKc/Cp4oXTE+c8yG4kew==$pCt+BZFILG+g7I+8JqoGFgg1PZv5Ez2fBsobPU9eWQE=:059Krypx720iSzpSKFBTeraSXpe49MUrRKT/affNOl8= |          | 
(1 row)

postgres=# alter role deleteme nologin;
ALTER ROLE
postgres=# select * from pg_shadow where usename = 'deleteme';
 usename | usesysid | usecreatedb | usesuper | userepl | usebypassrls | passwd | valuntil | useconfig 
---------+----------+-------------+----------+---------+--------------+--------+----------+-----------
(0 rows)

postgres=# alter role deleteme login;
ALTER ROLE
postgres=# select * from pg_shadow where usename = 'deleteme';
 usename  | usesysid | usecreatedb | usesuper | userepl | usebypassrls |                                                                passwd                                                                 | valuntil | useconfig 
----------+----------+-------------+----------+---------+--------------+---------------------------------------------------------------------------------------------------------------------------------------+----------+-----------
 deleteme |  2062883 | f           | f        | f       | f            | SCRAM-SHA-256$4096:DmdKc/Cp4oXTE+c8yG4kew==$pCt+BZFILG+g7I+8JqoGFgg1PZv5Ez2fBsobPU9eWQE=:059Krypx720iSzpSKFBTeraSXpe49MUrRKT/affNOl8= |          | 
(1 row)

postgres=# 

Also tested there: Setting / clearing login does not clear the password. I may find that useful as I deprecate users which are no longer required.

Sanitizing the list

Now is a great time to do some tidy up – I have a ticket open since 2021 to clean up unused users – finally, I have the perfect time to do that. No, that’s not a $WORK ticket; it’s something in my personal to-do list.

Here’s one way to convert a list to a set of commands:

[11:17 pro04 dvl ~] % echo 'john
michael
david
chris
mike
james
mark' | xargs -n 1 -I % echo alter user % nologin\;
alter user john nologin;
alter user michael nologin;
alter user david nologin;
alter user chris nologin;
alter user mike nologin;
alter user james nologin;
alter user mark nologin;

That could also be done within the SQL command. I’ll leave that as an exercise for you.

Resetting their passwords

I am sure I have the passwords for each of those users. It will be in a configuration file, ansible vault, and/or password manager, somewhere.

If I don’t have the password, is that user required? Let’s disable the login and find out. The nologin attribute can be set and unset without losing the password. I’ll use that later, but I’m not sure if you’ll see that work.

Now that I had the list of users, I wanted a document into which I could copy/paste the passwords. You might have this all scripted in a configuration tool. I don’t. I use Ansible and I see there is an Ansible PostgreSQL module and that is way more work than I want to take on now.

Instead, I’ll use this approach, then copy/paste in the passwords:

[13:12 pro04 dvl ~] % echo 'john
chris' | xargs -n 1 -I % echo alter user % password \'x\'\;
alter user john password 'x';
alter user chris password 'x';

It took me about 45 minutes to copy paste all those passwords in. And to also put them into ansible vault. It’s about time I put that in there.

Restarting applications

I gave some thought to restarting applications. No, that won’t be required. This change is only on the server and the passwords aren’t being changed, only reset to what they were so that the password can be rehashed using the new algorithm.

I suppose… given MD5 was not good enough, now would be a good time to reset all those passwords. Yet, I’m not going to do that.

First server done

I updated the first server today (pg03). Apart from getting one password wrong (commits_stage), everything has gone smoothy. I’ll wait until tomorrow before proceeding. That should allow all the regular cronjobs to run at least once.

The other servers are done now

By this time tomorrow, I’ll know if everything is good. All monitoring looks good.

Of note: I went to do the PostgreSQL database I have stored on AWS (within RDS) – there is nothing to be done there. I have no access to pg_authid (re https://www.thatguyfromdelhi.com/2017/03/using-pgdumpall-with-aws-rds-postgres.html). I had forgotten about this access issue and was expecting to have to update that database too. No, I don’t have to.

For now, I wait until tomorrow (2025-11-04 – election day in USA).

Election day

No errors seen overnight. My next step will be deletion of those users I set to nologin. I want to delete them for two reasons:

  1. they aren’t required
  2. their MD5 hashed passwords are generating warning messages on dbclone when it’s running the pg_restore tests

What I need now is a way to detect MD5 hashes without referencing the pg_shadow table. You will recall that when nologin is set, the user does not appear in the pg_shadow table. My first searches found nothing. I’ll check again later.

EDIT: The command is:

select rolname, rolpassword from pg_authid where rolpassword like 'md5%';

User deletes

I took the list of users previously set to nologin and issued drop user commands. Some could not be deleted:

template1=# drop user reading_dev_git;
ERROR:  role "reading_dev_git" cannot be dropped because some objects depend on it
DETAIL:  1 object in database freshports.dev-original
1 object in database freshports.dvl
1 object in database freshports.stage
1 object in database freshports.test
template1=# 

Stackoverflow to the rescue.

What I did was reassign objects to postgres, which is my preferred owner. You must be cautious here because this could lead to unintended privilege escalation.

NOTE: This REASSIGN command needs to be issued within each database in question. From above, for dan, in database freshports.dvl – otherwise, you won’t be able to do the drop.

template1=# drop user reading_dev_git;
ERROR:  role "reading_dev_git" cannot be dropped because some objects depend on it
DETAIL:  1 object in database freshports.dev-original
1 object in database freshports.dvl
1 object in database freshports.stage
1 object in database freshports.test
template1=# \c freshports.dvl
You are now connected to database "freshports.dvl" as user "postgres".
freshports.dvl=# REASSIGN OWNED BY reading_dev_git TO postgres;
REASSIGN OWNED
freshports.dvl=# \c freshports.stage
You are now connected to database "freshports.stage" as user "postgres".
freshports.stage=# REASSIGN OWNED BY reading_dev_git TO postgres;
REASSIGN OWNED
freshports.stage=# \c freshports.test
You are now connected to database "freshports.test" as user "postgres".
freshports.test=# REASSIGN OWNED BY reading_dev_git TO postgres;
REASSIGN OWNED

Then I dropped the user:

freshports.test=# drop user reading_dev_git;
ERROR:  role "reading_dev_git" cannot be dropped because some objects depend on it
DETAIL:  privileges for table categories
1 object in database freshports.dev-original
1 object in database freshports.dvl
1 object in database freshports.stage

No, I didn’t. Still more objects.

Here’s how I handled that: by removing permissions. Those permissions had existed from earlier days before I move to granting access to a role by a user (e.g. similar to adding the user to a group).

freshports.test=# \dp categories
                                    Access privileges
 Schema |    Name    | Type  |     Access privileges      | Column privileges | Policies 
--------+------------+-------+----------------------------+-------------------+----------
 public | categories | table | postgres=arwdDxt/postgres +|                   | 
        |            |       | www=rw/postgres           +|                   | 
        |            |       | commits=arw/postgres      +|                   | 
        |            |       | rsyncer=r/postgres        +|                   | 
        |            |       | reading_dev_git=r/postgres+|                   | 
        |            |       | reading_testgit=r/postgres+|                   | 
        |            |       | reading=r/postgres         |                   | 
(1 row)

freshports.test=# revoke all on categories from reading_dev_git
freshports.test-# ;
REVOKE
freshports.test=# revoke all on categories from reading_testgit;
REVOKE
freshports.test=# \c freshports.dev-original
You are now connected to database "freshports.dev-original" as user "postgres".
freshports.dev-original=# revoke all on categories from reading_testgit;
REVOKE
freshports.dev-original=# revoke all on categories from reading_dev_git;
REVOKE
freshports.dev-original=# \dp categories
                                   Access privileges
 Schema |    Name    | Type  |     Access privileges     | Column privileges | Policies 
--------+------------+-------+---------------------------+-------------------+----------
 public | categories | table | postgres=arwdDxt/postgres+|                   | 
        |            |       | www=rw/postgres          +|                   | 
        |            |       | commits=arw/postgres     +|                   | 
        |            |       | rsyncer=r/postgres       +|                   | 
        |            |       | reading=r/postgres        |                   | 
(1 row)

freshports.dev-original=# \c freshports.dvl
You are now connected to database "freshports.dvl" as user "postgres".
freshports.dvl=# revoke all on categories from reading_dev_git;
REVOKE
freshports.dvl=# revoke all on categories from reading_testgit;
REVOKE
freshports.dvl=# \c freshports.stage
You are now connected to database "freshports.stage" as user "postgres".
freshports.stage=# revoke all on categories from reading_dev_git;
REVOKE
freshports.stage=# revoke all on categories from reading_testgit;
REVOKE
freshports.stage=# drop user reading_dev_git;
DROP ROLE
freshports.stage=# drop user reading_testgit;
DROP ROLE
freshports.stage=# 

Again, I’ll wait until tomorrow before proceeding with the other databases.

Next day, more of the same

It’s getting to the point where having the passwords scripted would be way better than this.

As of this morning, I had these to resolve. I did some work, deleting users no longer required, setting passwords, and clearing passwords.

[21:45 dbclone dvl ~rsyncer/backups] % grep -l "PASSWORD 'md5"  $(find . -name globals.sql)
./zuul-pg02/database-backup/postgresql/globals.sql
./pg01/database-backup/postgresql/globals.sql
./x8dtu-pg01/database-backup/postgresql/globals.sql
./pg02/database-backup/postgresql/globals.sql
./bacula-database/postgresql/globals.sql
./papers/database-backup/postgresql/globals.sql
./pg03/database-backup/postgresql/globals.sql
./tallboy/database-backup/postgresql/globals.sql

Each one of those files is from a different database server.

Some roles are meant to be NOLOGIN. I fixed most of them with:

alter user commits password null;

Again, it’s a waiting game. :)

Although, I’m hopeful now that I found the pg_authid query mentioned above.

The next day

It is Friday, Nov 7 2025. There no MD5 warning so far. Although there is much left to do:

[13:05 dbclone dvl ~rsyncer/backups] % ps auwwx | grep postgres
postgres 19914 19.8  0.3  493456 374684  -  RsJ  12:53     0:57.38 postgres: postgres freshports.dev [local] CREATE INDEX (postgres)
postgres 36521 18.7  0.2  392052 282556  -  RsJ  13:04     0:16.75 postgres: parallel worker for PID 19914  (postgres)
postgres 19915 18.2  0.2  356316 306580  -  RsJ  12:53     0:34.65 postgres: postgres freshports.dev [local] CREATE INDEX (postgres)
postgres 36520 18.0  0.2  256988 215480  -  RsJ  13:04     0:16.58 postgres: parallel worker for PID 19915  (postgres)
postgres 36526 16.5  0.2  265968 212720  -  RsJ  13:04     0:14.99 postgres: parallel worker for PID 19908  (postgres)
postgres 19908 14.7  0.2  259824 210728  -  SsJ  12:53     6:11.55 postgres: postgres freshports.dev [local] CREATE INDEX (postgres)
postgres 36522 12.9  0.2  387956 272456  -  SsJ  13:04     0:11.27 postgres: parallel worker for PID 19913  (postgres)
postgres 19913 11.6  0.3  509812 388428  -  SsJ  12:53     0:27.95 postgres: postgres freshports.dev [local] CREATE INDEX (postgres)
postgres 19905 10.5  0.1  196868 169356  -  SsJ  12:53     3:37.68 postgres: postgres freshports.dev [local] COPY (postgres)
postgres 19910 10.0  0.3  554868 413548  -  SsJ  12:53     0:32.49 postgres: postgres freshports.dev [local] CREATE INDEX (postgres)
postgres 36525  6.8  0.2  388980 278128  -  RsJ  13:04     0:07.98 postgres: parallel worker for PID 19910  (postgres)
postgres 36523  5.3  0.2  418436 291328  -  SsJ  13:04     0:05.11 postgres: parallel worker for PID 19912  (postgres)
postgres 19912  4.9  0.3  531076 403136  -  DsJ  12:53     0:27.14 postgres: postgres freshports.dev [local] CREATE INDEX (postgres)
postgres 19911  4.4  0.2  326620 277308  -  SsJ  12:53     0:23.33 postgres: postgres freshports.dev [local] CREATE INDEX (postgres)
postgres 36524  4.3  0.2  294876 230548  -  SsJ  13:04     0:04.78 postgres: parallel worker for PID 19911  (postgres)
postgres 19812  2.1  0.1  193284 167492  -  SsJ  12:53     0:12.17 postgres: io worker 0 (postgres)
postgres 19815  1.0  0.1  195844 168888  -  SsJ  12:53     0:05.66 postgres: checkpointer  (postgres)
postgres 19900  0.8  0.0   21356   9736  -  SJ   12:53     0:41.80 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19813  0.1  0.1  193284 167716  -  SsJ  12:53     0:03.24 postgres: io worker 1 (postgres)
dvl      19770  0.0  0.0   14404   2892  -  IJ   12:53     0:00.00 /bin/sh /usr/home/dvl/bin/run-db-tests-postgresql /home/rsyncer/backups/pg03/database-backup /usr/home/dvl/logs/pg03.dbtest.log
dvl      19771  0.0  0.0   14404   2920  -  IJ   12:53     0:00.00 /bin/sh /usr/home/dvl/bin/test-postgresql-backups.sh /home/rsyncer/backups/pg03/database-backup
postgres 19811  0.0  0.0  193284  35948  -  IsJ  12:53     0:00.16 /usr/local/bin/postgres -D /var/db/postgres/data18 -c track_counts=off
postgres 19814  0.0  0.1  193284 166144  -  SsJ  12:53     0:00.62 postgres: io worker 2 (postgres)
postgres 19816  0.0  0.1  193284 167608  -  SsJ  12:53     0:01.25 postgres: background writer  (postgres)
postgres 19818  0.0  0.0  193284  36068  -  SsJ  12:53     0:02.41 postgres: walwriter  (postgres)
postgres 19819  0.0  0.0  195844  36332  -  IsJ  12:53     0:00.00 postgres: logical replication launcher  (postgres)
root     19897  0.0  0.0   21400   9664  -  IJ   12:53     0:00.01 /usr/local/bin/sudo -u postgres /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19898  0.0  0.0   21356   9676  -  IJ   12:53     0:00.05 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19901  0.0  0.0   21356   9736  -  IJ   12:53     0:07.12 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19902  0.0  0.0   21356   9736  -  IJ   12:53     0:03.01 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19903  0.0  0.0   21356   9736  -  IJ   12:53     0:02.92 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19904  0.0  0.0   21356   9736  -  IJ   12:53     0:01.13 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19906  0.0  0.0   21356   9736  -  IJ   12:53     0:01.09 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19907  0.0  0.0   21356   9736  -  IJ   12:53     0:01.19 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
postgres 19909  0.0  0.0   21356   9736  -  IJ   12:53     0:01.24 /usr/local/bin/pg_restore -j 8 --no-tablespaces -d freshports.dev /home/rsyncer/backups/pg03/database-backup/postgresql/freshports.dev.dump
dvl      47802  0.0  0.0   14404   2884  -  IsJ  06:03     0:00.00 /bin/sh -c /usr/bin/lockf -t 0 /tmp/.dvl.lockf.test-backups-all.sh ${HOME}/bin/test-backups-all.sh | egrep -v 'ERROR:  language "plpgsql" already exists|connect to local MySQL server through socket|createdb: error: database creation failed: ERROR:  database "postgres" already exists|pg_restore: error: could not execute query: ERROR:  role "rdsadmin" does not exist|pg_restore: warning: errors ignored on restore:|ERROR:  schema "public" already exists|ERROR:  there is no unique constraint matching given keys for referenced table'
dvl      47804  0.0  0.0   13836   2444  -  IJ   06:03     0:00.05 egrep -v ERROR:  language "plpgsql" already exists|connect to local MySQL server through socket|createdb: error: database creation failed: ERROR:  database "postgres" already exists|pg_restore: error: could not execute query: ERROR:  role "rdsadmin" does not exist|pg_restore: warning: errors ignored on restore:|ERROR:  schema "public" already exists|ERROR:  there is no unique constraint matching given keys for referenced table
dvl      38166  0.0  0.0   13836   2232  1  R+J  13:05     0:00.00 grep postgres

In comparison, this was yesterday:

[13:23 dbclone dvl ~/logs] % grep -l 'setting an MD5-encrypted password' *.log.0
bacula-database.dbtest.log.0
papers.dbtest.log.0
pg01.dbtest.log.0
pg02.dbtest.log.0
pg03.dbtest.log.0
tallboy.dbtest.log.0
x8dtu-pg01.dbtest.log.0
zuul-pg02.dbtest.log.0

And today:

[13:23 dbclone dvl ~/logs] % grep -l 'setting an MD5-encrypted password' *.log 
papers.dbtest.log
pg02.dbtest.log

That is an improvement, yet the testing process is only on pg03 – Let’s check again on Saturday morning.

That’s all folks

It took a few rounds, but eventually all the md5 hashes are gone. I hope there’s something in here which helps your process.

Some trailing words

A couple things which crossed my mind while writing this post.

about pg_hba.conf

At the top of this post, I listed several steps, one of which was “modify pg_hba.conf” – I realized this morning that I didn’t have to make that change. The pg_authid table clearly indicates the passwords are all SCRAM-SHA-256 hashes. Yet, the pg_hba.conf file specifies md5.

The answer is in the docs:

ram-sha-256
Perform SCRAM-SHA-256 authentication to verify the user’s password. See Section 20.5 for details.

md5
Perform SCRAM-SHA-256 or MD5 authentication to verify the user’s password. See Section 20.5 for details.

And under Password Authentication:

To ease transition from the md5 method to the newer SCRAM method, if md5 is specified as a method in pg_hba.conf but the user’s password on the server is encrypted for SCRAM (see below), then SCRAM-based authentication will automatically be chosen instead.

However, I will be updating my pg_hba.conf files and changing md5 to scram-sha-256 – this will ensure the systems are prepared for the eventual removal of md5 in a future release of PostgreSQL.

DROP OWNED

I mention DROP OWNED only because I went down that track. It was not what I wanted to do. But you may want to, one day.

You can use DROP OWNED but it removes all objects owned by the user. You don’t want that.

From the docs:

DROP OWNED drops all the objects within the current database that are owned by one of the specified roles. Any privileges granted to the given roles on objects in the current database or on shared objects (databases, tablespaces, configuration parameters) will also be revoked.

Use caution there.

Clean up

After you’ve made password changes like this, you may wish to sanitize ~/.psql_history – it will contain the command history and your passwords in clear text.

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Leave a Comment

Scroll to Top