Subject: [pgAdmin4][Patch]- Feature #7012 - disable master password requirement when using alternative auth source

From: Khushboo Vashi <[email-masked]>
Date: Mon, 11 Apr 2022 11:59:54 +0530

Hi,

Please find the attached patch to implement the feature #7012 - Disable
master password requirement when using alternative auth source

When pgAdmin stores a connection password, it encrypts it using a key that
is formed either from the master password, or from the pgAdmin login
password for the user. In the case of auth methods such as OAuth, Kerberos
or Webserver, pgAdmin doesn't have access to anything long-lived to form
the encryption key from, hence it uses the master password. And if the
master is disabled, there is no way to store the connection password.

To resolve this, we have added an option to config.py (which defaults to
None) for an alternate encryption key. pgAdmin would use this if a) the
master password is disabled AND b) there is no suitable key/password
available from the auth module for the user. If the option is set to None,
pgAdmin works as it does now.

Thanks,
Khushboo

---

From: Akshay Joshi <[email-masked]>
Date: Mon, 11 Apr 2022 13:49:49 +0530

Thanks, the patch applied.

On Mon, Apr 11, 2022 at 12:00 PM Khushboo Vashi <
[email-masked]> wrote:

> available from the auth module for the user. If the option is set to
> None, pgAdmin works as it does now.
>
> Thanks,
> Khushboo
>

-- 
*Thanks & Regards*
*Akshay Joshi*
*pgAdmin Hacker | Principal Software Architect*
*EDB Postgres <http://edbpostgres.com>*

*Mobile: +91 976-788-8246*

---

From: Dave Page <[email-masked]>
Date: Fri, 22 Apr 2022 09:31:36 +0100

Hi

On Mon, 11 Apr 2022 at 09:20, Akshay Joshi <[email-masked]>
wrote:

>> When pgAdmin stores a connection password, it encrypts it using a key
>> that is formed either from the master password, or from the pgAdmin login
This change has just been brought to my attention through other work. I
think this is poorly thought out, and could easily be made much more secure
and flexible than the current design.

Instead of effectively hard-coding a master password, which is only
slightly more secure than not having one in the first place, we should
allow the user to specify the path to a script or program that will return
a key. In a security-conscious environment, the script might query a
centralised key management system to securely retrieve the key to use. If a
user really wants the less secure implementation that this current patch
offers, then a simple script as follows would offer that (but would not be
recommended):

====
#!/bin/sh

echo "my secret key"
====

We would probably also want to allow use of a placeholder in which the
username can be passed, e.g.

MASTER_ENCRYPTION_KEY_SCRIPT = '/path/to/get-key.sh %u'

-- 
Dave Page
Blog: https://pgsnake.blogspot.com
Twitter: @pgsnake

EDB: https://www.enterprisedb.com

---

From: Khushboo Vashi <[email-masked]>
Date: Fri, 22 Apr 2022 14:27:48 +0530

On Fri, Apr 22, 2022 at 2:01 PM Dave Page <[email-masked]> wrote:

> Sounds good to me.
Does this mean we are going to remove the current implementation which
offers a hard-coded master password?

---

From: Dave Page <[email-masked]>
Date: Fri, 22 Apr 2022 10:04:10 +0100

On Fri, 22 Apr 2022 at 09:57, Khushboo Vashi <
[email-masked]> wrote:

>>>> To resolve this, we have added an option to config.py (which defaults
>>>> to None) for an alternate encryption key. pgAdmin would use this if a) the
Yes, I think that is the way to go. I don't want to add a config parameter
that doesn't seem like a good solution, and then remove it again in the
next release.

---

From: Khushboo Vashi <[email-masked]>
Date: Fri, 22 Apr 2022 14:38:20 +0530

On Fri, Apr 22, 2022 at 2:34 PM Dave Page <[email-masked]> wrote:

>>> On Mon, 11 Apr 2022 at 09:20, Akshay Joshi <
>>> [email-masked]> wrote:
>>>
>>>>> Please find the attached patch to implement the feature #7012 -
>>>>> Disable master password requirement when using alternative auth source
>>>>>
> Ok, In that case, we need to revert the patch and also need to update the
RM #7012 regarding our proposal.

---

From: Aditya Toshniwal <[email-masked]>
Date: Fri, 22 Apr 2022 15:18:25 +0530

Hi Dave,

Generally, secure keys like API_KEYS and all are supposed to be set in env
and are read by the app. Similar is the alternative encryption key.
People can run their scripts to export those config vars.

On Fri, Apr 22, 2022 at 2:38 PM Khushboo Vashi <
[email-masked]> wrote:

>> Yes, I think that is the way to go. I don't want to add a config
>> parameter that doesn't seem like a good solution, and then remove it again
>> in the next release.
>>

-- 
Thanks,
Aditya Toshniwal
pgAdmin Hacker | Software Architect | *edbpostgres.com*
<http://edbpostgres.com>
"Don't Complain about Heat, Plant a TREE"

---

From: Dave Page <[email-masked]>
Date: Fri, 22 Apr 2022 10:58:34 +0100

> People can run their scripts to export those config vars.

On the client side, yes. This is server side though. It's not uncommon on
the server side to include hooks to allow key retrieval from external key
management systems.

>>>>>>> When pgAdmin stores a connection password, it encrypts it using a
>>>>>>> key that is formed either from the master password, or from the pgAdmin
>>>>>>> login password for the user. In the case of auth methods such as OAuth,
>>>>>>> Kerberos or Webserver, pgAdmin doesn't have access to anything long-lived
>>>>>>> to form the encryption key from, hence it uses the master password. And if
>>>>>>> the master is disabled, there is no way to store the connection password.
>>>>>>>
>>>>>>> To resolve this, we have added an option to config.py (which
>>>>>>> defaults to None) for an alternate encryption key. pgAdmin would use this
>>>>>>> if a) the master password is disabled AND b) there is no suitable
>>>>>>> key/password available from the auth module for the user. If the
>>>>>>> option is set to None, pgAdmin works as it does now.
>>>>>>>
>>>>>>
>>>>> This change has just been brought to my attention through other work.
>>>>> I think this is poorly thought out, and could easily be made much more
>>>>> secure and flexible than the current design.
>>>>>
>>> Ok, In that case, we need to revert the patch and also need to update
>> the RM #7012 regarding our proposal.
>>
>>>
>>> --
>>> Dave Page

---

From: Aditya Toshniwal <[email-masked]>
Date: Fri, 22 Apr 2022 15:46:00 +0530

On Fri, Apr 22, 2022 at 3:28 PM Dave Page <[email-masked]> wrote:

>> Generally, secure keys like API_KEYS and all are supposed to be set in
>> env and are read by the app. Similar is the alternative encryption key.
Even on the server side. Like the AWS auth keys, or DB passwords. We can
include hooks, not against it. Just discussing.

>>>>>> We would probably also want to allow use of a placeholder in which
>>>>>> the username can be passed, e.g.
>>>>>>

---

From: Ashesh Vashi <[email-masked]>
Date: Fri, 22 Apr 2022 15:56:58 +0530

> include hooks, not against it. Just discussing.
Environment variables are good for static values.
Here - we're talking about dynamic data (per user security key), hence -
hooks are the best way forward.

-- Ashesh

>>>>>>> This change has just been brought to my attention through other
>>>>>>> work. I think this is poorly thought out, and could easily be made much
>>>>>>> more secure and flexible than the current design.
>>>>>>>
>>>>>> Does this mean we are going to remove the current implementation
>>>>>> which offers a hard-coded master password?
>>>>>>
>>>>>>>

---

From: Dave Page <[email-masked]>
Date: Fri, 22 Apr 2022 11:27:36 +0100

> include hooks, not against it. Just discussing.

If you're using an AWS auth key on a server, then you're acting as a client
for AWS - and DB passwords are a great example of why using a hook is a
good thing; it's a very common request from users to have a secure way to
retrieve credentials from an external service. Not to mention that a DB
password is needed on the client side of a connection, not on the server
side. On the server side, the database would query LDAP/Kerberos/whatever.

A better example would be querying a key management service to unlock an
encrypted disk or something like the service Bruce wrote for managing
pgcrypto keys.

---

From: Aditya Toshniwal <[email-masked]>
Date: Fri, 22 Apr 2022 16:01:02 +0530

On Fri, Apr 22, 2022 at 3:57 PM Dave Page <[email-masked]> wrote:

>>> On the client side, yes. This is server side though. It's not uncommon
>>> on the server side to include hooks to allow key retrieval from external
>>> key management systems.
>>>
> If you're using an AWS auth key on a server, then you're acting as a
> client for AWS - and DB passwords are a great example of why using a hook
> is a good thing; it's a very common request from users to have a secure way
> to retrieve credentials from an external service. Not to mention that a DB

Got it. Thanks.

---

From: Yogesh Mahajan <[email-masked]>
Date: Wed, 3 May 2023 15:14:22 +0530

Hi Dave/Team,

As per the new design, pgAdmin should add a config to specify a path for
script/program to retrieve an encryption key & use it to encrypt the
passwords.
The script/program will be at an application level and not a user level.
This feature will be applicable only in case of server mode as we are going
to use OS level secret storage for the same in Desktop mode.

Thanks,
Yogesh Mahajan
EnterpriseDB

On Fri, Apr 22, 2022 at 4:01 PM Aditya Toshniwal <
[email-masked]> wrote:

>>>>>>>>>>> When pgAdmin stores a connection password, it encrypts it using
>>>>>>>>>>> a key that is formed either from the master password, or from the pgAdmin
>>>>>>>>>>> key/password available from the auth module for the user. If
>>>>>>>>>>> the option is set to None, pgAdmin works as it does now.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>> Instead of effectively hard-coding a master password, which is
>>>>>>>>> only slightly more secure than not having one in the first place, we should
>>>>>>> Ok, In that case, we need to revert the patch and also need to
>>>>>> update the RM #7012 regarding our proposal.
>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Dave Page

---

From: Dave Page <[email-masked]>
Date: Wed, 3 May 2023 14:41:51 +0100

> script/program to retrieve an encryption key & use it to encrypt the

Right.

> to use OS level secret storage for the same in Desktop mode.

Yes. However, we can pass parameters to the hook. For example, we might do
something like:

MASTER_PASSWORD_HOOK = '/path/to/key_client.sh %U %E'

Where at runtime %U is replaced with the username and %E is replaced with
the user's email address.

Those are just examples of course - there may be other parameters that make
sense to make available.

>>>>>> Generally, secure keys like API_KEYS and all are supposed to be set
>>>>>> in env and are read by the app. Similar is the alternative encryption key.
>>>> Even on the server side. Like the AWS auth keys, or DB passwords. We
>>>> can include hooks, not against it. Just discussing.
>>>>
>>>
>>>>>>>>>> We would probably also want to allow use of a placeholder in
>>>>>>>>>> which the username can be passed, e.g.
>>>>>>>>>>

-- 
Dave Page
VP, Chief Architect, Database Infrastructure
Blog: https://www.enterprisedb.com/dave-page
Twitter: @pgsnake