When you want to know the currently connected user in PostgreSQL for your session there are two system information functions which seem to do the same thing. There is “session_user” and there is “current_user”. So what is the difference between those or is there no difference at all?
Looking at my users in PostgreSQL all I have right now is the “postgres” superuser:
1 2 3 4 5 | postgres=# \du List of roles Role name | Attributes -----------+------------------------------------------------------------ postgres | Superuser, Create role, Create DB, Replication, Bypass RLS |
Both system information functions return the same result:
1 2 3 4 5 6 7 8 9 10 11 | postgres=# select current_user ; current_user -------------- postgres (1 row) postgres=# select session_user ; session_user -------------- postgres (1 row) |
Let’s create a new login role:
1 2 3 4 5 6 7 8 | postgres=# create user a with login password 'a' ; CREATE ROLE postgres=# \du List of roles Role name | Attributes -----------+------------------------------------------------------------ a | postgres | Superuser, Create role, Create DB, Replication, Bypass RLS |
What do those functions return when we connect with the new user?
1 2 3 4 5 6 7 8 9 10 11 12 13 | postgres=# \c postgres a You are now connected to database "postgres" as user "a" . postgres=> select current_user ; current_user -------------- a (1 row) postgres=> select session_user ; session_user -------------- a (1 row) |
Same story as above, both return the same result. Things get different if you use “set role“:
1 2 3 4 5 6 7 8 9 | postgres=# \c postgres postgres You are now connected to database "postgres" as user "postgres" . postgres=# set role a; SET postgres=> select current_user , session_user ; current_user | session_user --------------+-------------- a | postgres (1 row) |
The session user is still “postgres”, but the current user now is “a”. This also means, that permission checks are now done for user “a” and not for “postgres” anymore:
1 2 3 4 5 6 7 | postgres=> create table t(a int ); ERROR: permission denied for schema public LINE 1: create table t(a int ); ^ postgres=> create schema a; ERROR: permission denied for database postgres postgres=> |
Going back to the initial state can be done with “set role none”:
1 2 3 4 5 6 7 | postgres=> set role none; SET postgres=# select current_user , session_user ; current_user | session_user --------------+-------------- postgres | postgres (1 row) |
There is also “set session authorization“, which behave slightly different:
1 2 3 4 5 6 7 8 9 | postgres=# set session authorization a; SET postgres=> select current_user , session_user ; current_user | session_user --------------+-------------- a | a (1 row) postgres=> |
The current user might also change in security definer functions, but the session user can’t. The current user is the one which is relevant for permission checking.