Thread

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. MergeAttributes: convert pg_attribute back to ColumnDef before comparing

  1. [PoC/RFC] Multiple passwords, interval expirations

    Joshua Brindle <joshua.brindle@crunchydata.com> — 2022-03-02T14:58:16Z

    This is not intended for PG15.
    
    Attached are a proof of concept patchset to implement multiple valid
    passwords, which have independent expirations, set by a GUC or SQL
    using an interval.
    
    This allows the superuser to set a password validity period of e.g.,
    60 days, and for users to create new passwords before the old ones
    expire, and use both until the old one expires. This will aid in
    password rollovers for apps and other systems that need to connect
    with password authentication.
    
    The first patch simply moves password to a new catalog, no functional changes.
    The second patch allows multiple passwords to be used simultaneously.
    The third adds per-password expiration, SQL grammar, and the GUC.
    
    Some future work intended to build on this includes:
    - disallowing password reuse
    - transitioning between password mechanisms
    
    Example output (note the NOTICES can go away, but are helpful for
    demo/testing purposes):
    
    postgres=# alter system set password_valid_duration = '1 day';
    NOTICE:  Setting password duration to "1 day"
    ALTER SYSTEM
    postgres=# select pg_reload_conf();
     pg_reload_conf
    ----------------
     t
    (1 row)
    
    postgres=# create user joshua password 'a' expires in '5 minutes';
    NOTICE:  Setting password duration to "1 day"
    NOTICE:  Password will expire at: "2022-03-02 14:52:31.217193" (from SQL)
    CREATE ROLE
    
    ---
    
    $ psql -h 127.0.0.1 -U joshua postgres
    Password for user joshua:
    psql (12.7, server 15devel)
    WARNING: psql major version 12, server major version 15.
             Some psql features might not work.
    Type "help" for help.
    
    postgres=> alter role joshua passname 'newone' password 'asdf' expires
    in '1 year';
    ERROR:  must be superuser to override password_validity_duration GUC
    postgres=> alter role joshua passname 'newone' password 'asdf';
    NOTICE:  Password will expire at: "2022-03-03 14:47:53.728159" (from GUC)
    ALTER ROLE
    postgres=>
    
    --
    
    postgres=# select * from pg_auth_password ;
     roleid |  name   |
               password
                        |          expiration
    --------+---------+-------------------------------------------------------------------------------------------------------------------
    --------------------+-------------------------------
         10 | __def__ |
    SCRAM-SHA-256$4096:yGiHIYPwc2az7xj/7TIyTA==$OQL/AEcEY1yOCNbrZEj4zDvNnOLpIqltOW1uQvosLvc=:9VRRppuIkSrwhiBN5ePy8wB1y
    zDa/2uX0WUx6gXi93E= |
      16384 | __def__ |
    SCRAM-SHA-256$4096:AAAAAAAAAAAAAAAAAAAAAA==$1Ivp4d+vAWxowpuGEn05KR9lxyGOms3yy85k3D7XpBg=:k8xUjU6xrJG17PMGa/Zya6pAE
    /M7pEDaoIFmWvNIEUg= | 2022-03-02 06:52:31.217193-08
      16384 | newone  |
    SCRAM-SHA-256$4096:AAAAAAAAAAAAAAAAAAAAAA==$WK3+41CCGDognSnZrtpHhv00z9LuVUjHR1hWq8T1+iE=:w2C5GuhgiEB7wXqPxYfxBKB+e
    hm4h6Oeif1uzpPIFVk= | 2022-03-03 06:47:53.728159-08
    (3 rows)
    
  2. Re: [PoC/RFC] Multiple passwords, interval expirations

    Joshua Brindle <joshua.brindle@crunchydata.com> — 2022-03-02T15:35:44Z

    On Wed, Mar 2, 2022 at 9:58 AM Joshua Brindle
    <joshua.brindle@crunchydata.com> wrote:
    >
    > This is not intended for PG15.
    >
    > Attached are a proof of concept patchset to implement multiple valid
    > passwords, which have independent expirations, set by a GUC or SQL
    > using an interval.
    >
    
    <snip>
    
    > postgres=# select * from pg_auth_password ;
    >  roleid |  name   |
    >            password
    >                     |          expiration
    > --------+---------+-------------------------------------------------------------------------------------------------------------------
    > --------------------+-------------------------------
    >      10 | __def__ |
    > SCRAM-SHA-256$4096:yGiHIYPwc2az7xj/7TIyTA==$OQL/AEcEY1yOCNbrZEj4zDvNnOLpIqltOW1uQvosLvc=:9VRRppuIkSrwhiBN5ePy8wB1y
    > zDa/2uX0WUx6gXi93E= |
    >   16384 | __def__ |
    > SCRAM-SHA-256$4096:AAAAAAAAAAAAAAAAAAAAAA==$1Ivp4d+vAWxowpuGEn05KR9lxyGOms3yy85k3D7XpBg=:k8xUjU6xrJG17PMGa/Zya6pAE
    > /M7pEDaoIFmWvNIEUg= | 2022-03-02 06:52:31.217193-08
    >   16384 | newone  |
    > SCRAM-SHA-256$4096:AAAAAAAAAAAAAAAAAAAAAA==$WK3+41CCGDognSnZrtpHhv00z9LuVUjHR1hWq8T1+iE=:w2C5GuhgiEB7wXqPxYfxBKB+e
    > hm4h6Oeif1uzpPIFVk= | 2022-03-03 06:47:53.728159-08
    > (3 rows)
    
    There's obviously a salt problem here that I'll need to fix that
    apparently snuck in at the last rebase, but this brings up one aspect
    of the patchset I didn't mention in the original email:
    
    For the SCRAM protocol to work as is with existing clients the salt
    for each password must be the same. Right now ALTER USER will find and
    reuse the salt, but a user passing in a pre-computed SCRAM secret
    currently has no way to get the salt.
    
    for \password (we'll need a new one that takes a password name) I was
    thinking libpq could hold onto the salt that was used to log in, but
    for outside computation we'll need some way for the client to request
    it.
    
    None of that is done yet.
    
    
    
    
  3. Re: [PoC/RFC] Multiple passwords, interval expirations

    Joshua Brindle <joshua.brindle@crunchydata.com> — 2022-03-02T18:02:18Z

    On Wed, Mar 2, 2022 at 10:35 AM Joshua Brindle
    <joshua.brindle@crunchydata.com> wrote:
    >
    > On Wed, Mar 2, 2022 at 9:58 AM Joshua Brindle
    > <joshua.brindle@crunchydata.com> wrote:
    > >
    > > This is not intended for PG15.
    > >
    > > Attached are a proof of concept patchset to implement multiple valid
    > > passwords, which have independent expirations, set by a GUC or SQL
    > > using an interval.
    > >
    >
    > <snip>
    >
    > > postgres=# select * from pg_auth_password ;
    > >  roleid |  name   |
    > >            password
    > >                     |          expiration
    > > --------+---------+-------------------------------------------------------------------------------------------------------------------
    > > --------------------+-------------------------------
    > >      10 | __def__ |
    > > SCRAM-SHA-256$4096:yGiHIYPwc2az7xj/7TIyTA==$OQL/AEcEY1yOCNbrZEj4zDvNnOLpIqltOW1uQvosLvc=:9VRRppuIkSrwhiBN5ePy8wB1y
    > > zDa/2uX0WUx6gXi93E= |
    > >   16384 | __def__ |
    > > SCRAM-SHA-256$4096:AAAAAAAAAAAAAAAAAAAAAA==$1Ivp4d+vAWxowpuGEn05KR9lxyGOms3yy85k3D7XpBg=:k8xUjU6xrJG17PMGa/Zya6pAE
    > > /M7pEDaoIFmWvNIEUg= | 2022-03-02 06:52:31.217193-08
    > >   16384 | newone  |
    > > SCRAM-SHA-256$4096:AAAAAAAAAAAAAAAAAAAAAA==$WK3+41CCGDognSnZrtpHhv00z9LuVUjHR1hWq8T1+iE=:w2C5GuhgiEB7wXqPxYfxBKB+e
    > > hm4h6Oeif1uzpPIFVk= | 2022-03-03 06:47:53.728159-08
    > > (3 rows)
    >
    > There's obviously a salt problem here that I'll need to fix that
    > apparently snuck in at the last rebase, but this brings up one aspect
    > of the patchset I didn't mention in the original email:
    >
    
    Attached are fixed patches rebased against the lastest master.
    
    
    > For the SCRAM protocol to work as is with existing clients the salt
    > for each password must be the same. Right now ALTER USER will find and
    > reuse the salt, but a user passing in a pre-computed SCRAM secret
    > currently has no way to get the salt.
    >
    > for \password (we'll need a new one that takes a password name) I was
    > thinking libpq could hold onto the salt that was used to log in, but
    > for outside computation we'll need some way for the client to request
    > it.
    >
    > None of that is done yet.
    
  4. Re: [PoC/RFC] Multiple passwords, interval expirations

    Joshua Brindle <joshua.brindle@crunchydata.com> — 2022-04-08T17:04:22Z

    > > On Wed, Mar 2, 2022 at 9:58 AM Joshua Brindle
    > > <joshua.brindle@crunchydata.com> wrote:
    > > >
    > > > This is not intended for PG15.
    > > >
    > > > Attached are a proof of concept patchset to implement multiple valid
    > > > passwords, which have independent expirations, set by a GUC or SQL
    > > > using an interval.
    > > >
    > >
    > > <snip>
    > >
    > > > postgres=# select * from pg_auth_password ;
    > > >  roleid |  name   |
    > > >            password
    > > >                     |          expiration
    > > > --------+---------+-------------------------------------------------------------------------------------------------------------------
    > > > --------------------+-------------------------------
    > > >      10 | __def__ |
    > > > SCRAM-SHA-256$4096:yGiHIYPwc2az7xj/7TIyTA==$OQL/AEcEY1yOCNbrZEj4zDvNnOLpIqltOW1uQvosLvc=:9VRRppuIkSrwhiBN5ePy8wB1y
    > > > zDa/2uX0WUx6gXi93E= |
    > > >   16384 | __def__ |
    > > > SCRAM-SHA-256$4096:AAAAAAAAAAAAAAAAAAAAAA==$1Ivp4d+vAWxowpuGEn05KR9lxyGOms3yy85k3D7XpBg=:k8xUjU6xrJG17PMGa/Zya6pAE
    > > > /M7pEDaoIFmWvNIEUg= | 2022-03-02 06:52:31.217193-08
    > > >   16384 | newone  |
    > > > SCRAM-SHA-256$4096:AAAAAAAAAAAAAAAAAAAAAA==$WK3+41CCGDognSnZrtpHhv00z9LuVUjHR1hWq8T1+iE=:w2C5GuhgiEB7wXqPxYfxBKB+e
    > > > hm4h6Oeif1uzpPIFVk= | 2022-03-03 06:47:53.728159-08
    > > > (3 rows)
    > >
    > > There's obviously a salt problem here that I'll need to fix that
    > > apparently snuck in at the last rebase, but this brings up one aspect
    > > of the patchset I didn't mention in the original email:
    > >
    >
    > Attached are fixed patches rebased against the lastest master.
    >
    >
    > > For the SCRAM protocol to work as is with existing clients the salt
    > > for each password must be the same. Right now ALTER USER will find and
    > > reuse the salt, but a user passing in a pre-computed SCRAM secret
    > > currently has no way to get the salt.
    > >
    > > for \password (we'll need a new one that takes a password name) I was
    > > thinking libpq could hold onto the salt that was used to log in, but
    > > for outside computation we'll need some way for the client to request
    > > it.
    > >
    > > None of that is done yet.
    
    Now that the commitfest is over these are rebased on master.
    
    It's unclear if I will be able to continue working on this featureset,
    this email address will be inactive after today.
    
  5. Re: [PoC/RFC] Multiple passwords, interval expirations

    Jacob Champion <jchampion@timescale.com> — 2022-06-29T21:21:53Z

    On 4/8/22 10:04, Joshua Brindle wrote:
    > It's unclear if I will be able to continue working on this featureset,
    > this email address will be inactive after today.
    
    I'm assuming the answer to this was "no". Is there any interest out
    there to pick this up for the July CF?
    
    --Jacob
    
    
    
    
  6. Re: [PoC/RFC] Multiple passwords, interval expirations

    Stephen Frost <sfrost@snowman.net> — 2022-06-29T21:27:37Z

    Greetings,
    
    On Wed, Jun 29, 2022 at 17:22 Jacob Champion <jchampion@timescale.com>
    wrote:
    
    > On 4/8/22 10:04, Joshua Brindle wrote:
    > > It's unclear if I will be able to continue working on this featureset,
    > > this email address will be inactive after today.
    >
    > I'm assuming the answer to this was "no". Is there any interest out
    > there to pick this up for the July CF?
    
    
    Short answer to that is yes, I’m interested in continuing this (though
    certainly would welcome it if there are others who are also interested, and
    may be able to bring someone else to help work on it too but that might be
    more August / September time frame).
    
    Thanks,
    
    Stephen
    
    >
    
  7. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2022-06-30T23:53:58Z

    I am planning on picking it up next week; right now picking up steam,
    and reviewing a different, smaller patch.
    
    At his behest, I had a conversation with Joshua (OP), and have his
    support to pick up and continue working on this patch. I have a some
    ideas of my own, on what this patch should do, but since I haven't
    fully reviewed the (bulky) patch, I'll reserve my proposals until I
    wrap my head around it.
    
    Please expect some activity on this patch towards the end of next week.
    
    BCC: Joshua's new work email.
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
    On Wed, Jun 29, 2022 at 2:27 PM Stephen Frost <sfrost@snowman.net> wrote:
    >
    > Greetings,
    >
    > On Wed, Jun 29, 2022 at 17:22 Jacob Champion <jchampion@timescale.com> wrote:
    >>
    >> On 4/8/22 10:04, Joshua Brindle wrote:
    >> > It's unclear if I will be able to continue working on this featureset,
    >> > this email address will be inactive after today.
    >>
    >> I'm assuming the answer to this was "no". Is there any interest out
    >> there to pick this up for the July CF?
    >
    >
    > Short answer to that is yes, I’m interested in continuing this (though certainly would welcome it if there are others who are also interested, and may be able to bring someone else to help work on it too but that might be more August / September time frame).
    >
    > Thanks,
    >
    > Stephen
    
    
    
    
  8. Re: [PoC/RFC] Multiple passwords, interval expirations

    Stephen Frost <sfrost@snowman.net> — 2022-07-01T00:20:34Z

    Greetings,
    
    * Gurjeet Singh (gurjeet@singh.im) wrote:
    > I am planning on picking it up next week; right now picking up steam,
    > and reviewing a different, smaller patch.
    
    Great!  Glad that others are interested in this.
    
    > At his behest, I had a conversation with Joshua (OP), and have his
    > support to pick up and continue working on this patch. I have a some
    > ideas of my own, on what this patch should do, but since I haven't
    > fully reviewed the (bulky) patch, I'll reserve my proposals until I
    > wrap my head around it.
    
    I'd be curious as to your thought as to what the patch should be doing.
    Joshua and I had discussed it at some length as he was working on it.
    
    > Please expect some activity on this patch towards the end of next week.
    
    I've gone ahead and updated it, cleaned up a couple things, and make it
    so that check-world actually passes with it.  Attached is an updated
    version and I'll add it to the July commitfest.
    
    Thanks!
    
    Stephen
    
  9. Re: [PoC/RFC] Multiple passwords, interval expirations

    Brindle, Joshua <joshuqbr@amazon.com> — 2022-07-01T14:50:56Z

    On 6/30/22 8:20 PM, Stephen Frost wrote:
    > Greetings,
    >
    > * Gurjeet Singh (gurjeet@singh.im) wrote:
    >> I am planning on picking it up next week; right now picking up steam,
    >> and reviewing a different, smaller patch.
    > Great!  Glad that others are interested in this.
    >
    >> At his behest, I had a conversation with Joshua (OP), and have his
    >> support to pick up and continue working on this patch. I have a some
    >> ideas of my own, on what this patch should do, but since I haven't
    >> fully reviewed the (bulky) patch, I'll reserve my proposals until I
    >> wrap my head around it.
    > I'd be curious as to your thought as to what the patch should be doing.
    > Joshua and I had discussed it at some length as he was working on it.
    
    
    Adding myself to the CC list here /waves
    
    
    I gave Gurjeet a bit of a brain dump on what I had planned (and what 
    we'd talked about), though he's free to take it in a different direction 
    if he wants.
    
    
    >> Please expect some activity on this patch towards the end of next week.
    > I've gone ahead and updated it, cleaned up a couple things, and make it
    > so that check-world actually passes with it.  Attached is an updated
    > version and I'll add it to the July commitfest.
    
    
    Ah, thanks. Hopefully it wasn't too horrible of a rebase.
    
    
    > Thanks!
    >
    > Stephen
    
    
    
    
  10. Re: [PoC/RFC] Multiple passwords, interval expirations

    Stephen Frost <sfrost@snowman.net> — 2022-07-01T15:13:35Z

    Greetings,
    
    On Fri, Jul 1, 2022 at 10:51 Brindle, Joshua <joshuqbr@amazon.com> wrote:
    
    >
    > On 6/30/22 8:20 PM, Stephen Frost wrote:
    > > * Gurjeet Singh (gurjeet@singh.im) wrote:
    > >> I am planning on picking it up next week; right now picking up steam,
    > >> and reviewing a different, smaller patch.
    > > Great!  Glad that others are interested in this.
    > >
    > >> At his behest, I had a conversation with Joshua (OP), and have his
    > >> support to pick up and continue working on this patch. I have a some
    > >> ideas of my own, on what this patch should do, but since I haven't
    > >> fully reviewed the (bulky) patch, I'll reserve my proposals until I
    > >> wrap my head around it.
    > > I'd be curious as to your thought as to what the patch should be doing.
    > > Joshua and I had discussed it at some length as he was working on it.
    >
    >
    > Adding myself to the CC list here /waves
    
    
    Hi!
    
    I gave Gurjeet a bit of a brain dump on what I had planned (and what
    > we'd talked about), though he's free to take it in a different direction
    > if he wants.
    
    
    Perhaps though would certainly like this to patch to be useful for the
    use-cases that we had discussed, naturally. :)
    
    >> Please expect some activity on this patch towards the end of next week.
    > > I've gone ahead and updated it, cleaned up a couple things, and make it
    > > so that check-world actually passes with it.  Attached is an updated
    > > version and I'll add it to the July commitfest.
    >
    > Ah, thanks. Hopefully it wasn't too horrible of a rebase.
    
    
    Wasn’t too bad.. needs more clean-up, there was some white space issues and
    some simple re-base stuff, but then the support for “md5” pg_hba option was
    broken for users with SCRAM passwords because we weren’t checking if there
    was a SCRAM pw stored and upgrading to SCRAM in that case.  That’s the main
    case that I fixed.  We will need to document this though, of course.  The
    patch I submitted should basically do:
    
    pg_hba md5 + md5-only pws -> md5 auth used
    pg_hba md5 + scram-only pws -> scram
    pg_hba md5 + md5 and scram pws -> scram
    pg_hba scram -> scram
    
    Not sure if we need to try and do something to make it possible to have
    pg_hba md5 + mixed pws and have md5 used but it’s tricky as we would have
    to know on the server side early on if that’s what we want to do.  We could
    add an option to md5 to say “only do md5” maybe but I’m also inclined to
    not bother and tell people to just get moved to scram already.
    
    For my 2c, I’d also like to move to having a separate column for the PW
    type from the actual secret but that’s largely an independent change.
    
    Thanks!
    
    Stephen
    
    >
    
  11. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-09-25T07:31:43Z

    On Fri, Jul 1, 2022 at 8:13 AM Stephen Frost <sfrost@snowman.net> wrote:
    > On Fri, Jul 1, 2022 at 10:51 Brindle, Joshua <joshuqbr@amazon.com> wrote:
    >> On 6/30/22 8:20 PM, Stephen Frost wrote:
    
    >> > I've gone ahead and updated it, cleaned up a couple things, and make it
    >> > so that check-world actually passes with it.  Attached is an updated
    >> > version and I'll add it to the July commitfest.
    >>
    >> Ah, thanks. Hopefully it wasn't too horrible of a rebase.
    >
    > Wasn’t too bad.. needs more clean-up, there was some white space issues and some simple re-base stuff, but then the support for “md5” pg_hba option was broken for users with SCRAM passwords because we weren’t checking if there was a SCRAM pw stored and upgrading to SCRAM in that case.  That’s the main case that I fixed.  We will need to document this though, of course.  The patch I submitted should basically do:
    >
    > pg_hba md5 + md5-only pws -> md5 auth used
    > pg_hba md5 + scram-only pws -> scram
    > pg_hba md5 + md5 and scram pws -> scram
    > pg_hba scram -> scram
    >
    > Not sure if we need to try and do something to make it possible to have pg_hba md5 + mixed pws and have md5 used but it’s tricky as we would have to know on the server side early on if that’s what we want to do.  We could add an option to md5 to say “only do md5” maybe but I’m also inclined to not bother and tell people to just get moved to scram already.
    >
    > For my 2c, I’d also like to move to having a separate column for the PW type from the actual secret but that’s largely an independent change.
    
    The docs say this about rolpassword in case it stores SCRAM-SHA-256
    encrypted password "If the password is encrypted with SCRAM-SHA-256,
    it has the format SCRAM-SHA-256$... This format is the same as that
    specified by RFC-5803". So I believe our hands are tied, and we
    cannot change that without breaking compliance with RFC 5803.
    
    Please see attached v4 of the patch. The patch takes care of rebase to
    the master/17-devel branch, and includes some changes, too. The
    rebase/merge conflicts were quite involved, since some affected files
    had been removed, or even split into multiple files over the course of
    the last year; resolving merge-conflicts was more of a grunt work.
    
    The changes since V3 are (compare [1] vs. [2], Git branches linked below):
    - Remove TOAST table and corresponding index from pg_authid.
    - Fix memory leak/allocation bug; replace malloc() with guc_alloc().
    - Fix assumptions about passed-in double-pointers to GUC handling functions.
    - Remove the new function is_role_valid() and its call sites, because
    I believe it made backward-incompatible change to authentication
    behavior (see more below).
    - Improve error handling that was missing at a few places.
    - Remove unnecessary checks, like (*var != NULL) checks when we know
    all callers pass a NULL by convention.
    - Replace MemSet() calls with var={0} styled initialization.
    - Minor edits to docs to change them from pg_authid to pg_auth_password.
    
    More details about why I chose to remove is_role_valid() and revert to
    the old code:
    is_role_valid() was a new function that pulled out a small section of
    code from get_role_passwords() . I don't think moving this code block
    to a new function gains us anything; in fact, it now forces us to call
    the new function in two new locations, which we didn't have to do
    before. It has to throw the same error messages as before, to maintain
    compatibility with external tools/libraries, hence it duplicates those
    messages as well, which is not ideal.
    
    Moreover, before the patch, in case of CheckPasswordAuth(), the error
    (if any) would have been thrown _after_ network communication done by
    sendAuthRequest() call. But with this patch, the error is thrown
    before the network interaction, hence this changes the order of
    network interaction and the error message. This may have security
    implications, too, but I'm unable to articulate one right now.
    
    If we really want the role-validity check to be a function of its own,
    a separate patch can address that; this patch doesn't have to make
    that decision.
    
    Open question: If a client is capable of providing just md5 passwords
    handshake, and because of pg_hba.conf setting, or because the role has
    at least one SCRAM password (essentially the 3rd case you mention
    above: pg_hba md5 + md5 and scram pws -> scram), the server will
    respond with a SASL/SCRAM authentication response, and that would
    break the backwards compatibility and will deny access to the client.
    Does this make it necessary to use a newer libpq/client library?
    
    Before the patch, the rolvaliduntil was used to check and complain
    that the password has expired, as the docs explicitly state that
    rolvaliduntil represents "Password expiry time (only used for password
    authentication); null if no expiration" . Keeping that column after
    the introduction of per-password expiry times now separates the
    role-validity from password validity. During an internal discussion a
    curiosity arose whether we can simply remove rolvaliduntil. And I
    believe the answer is yes, primarily because of how the docs describe
    the column. So my proposal is to remove rolvaliduntil from pg_authid,
    and on a case-by-case basis, optionally replace its uses with
    max(pg_auth_password.expiration).
    
    Comments?
    
    Next steps:
    - Break the patch into smaller patches.
    - Address TODO items
    - Comment each new function
    - Add tests
    - Add/update documentation
    
    PS: Since this is a large patch, and because in some portions the code
    has been indented by a level or two (e.g. to run a `for` loop over
    existing code for single-password), I have found the following Git
    command to be helpful in reviewing the changes between master and this
    branch,: `git diff -b --color-words -U20 origin/master...HEAD -- `
    
    [1]: v3 patch, applied to a contemporary commit on master branch
    https://github.com/gurjeet/postgres/commits/multiple_passwords_v3
    
    [2]: main development branch, patch rebased to current master branch,
    followed by many changes
    https://github.com/gurjeet/postgres/commits/multiple_passwords
    
    
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
  12. Re: [PoC/RFC] Multiple passwords, interval expirations

    Jeff Davis <pgsql@j-davis.com> — 2023-09-26T23:36:31Z

    On Mon, 2023-09-25 at 00:31 -0700, Gurjeet Singh wrote:
    
    > Please see attached v4 of the patch. The patch takes care of rebase
    > to
    > the master/17-devel branch, and includes some changes, too.
    
    FWIW I got some failures applying. I didn't investigate much, and
    instead I looked at your git branch (7a35619e).
    
    > Moreover, before the patch, in case of CheckPasswordAuth(), the error
    > (if any) would have been thrown _after_ network communication done by
    > sendAuthRequest() call. But with this patch, the error is thrown
    > before the network interaction, hence this changes the order of
    > network interaction and the error message. This may have security
    > implications, too, but I'm unable to articulate one right now.
    
    You mean before v3 or before v4? Is this currently a problem in v4?
    
    > Open question: If a client is capable of providing just md5 passwords
    > handshake, and because of pg_hba.conf setting, or because the role
    > has
    > at least one SCRAM password (essentially the 3rd case you mention
    > above: pg_hba md5 + md5 and scram pws -> scram), the server will
    > respond with a SASL/SCRAM authentication response, and that would
    > break the backwards compatibility and will deny access to the client.
    > Does this make it necessary to use a newer libpq/client library?
    
    Perhaps you can try the MD5 passwords first, and only if they fail,
    move on to try scram passwords?
    
    > Comments?
    
    IIUC, for the case of multiple scram passwords, we use the salt to
    select the right scram password, and then proceed from there?
    
    I'm not very excited about the idea of naming passwords, or having
    passwords with default names. I can't think of anything better right
    now, so it might be OK.
    
    > - Add tests
    > - Add/update documentation
    
    These are needed to provide better review.
    
    
    Regards,
    	Jeff Davis
    
    
    
    
    
  13. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-05T05:41:15Z

    I had an idea to simplify this feature/patch and after some validation
    in internal discussions, I am posting the new approach here. I'd
    appreciate any feedback and comments.
    
    To begin with, the feature we are chasing is to make it convenient for
    the users to rollover their passwords. Currently there is no easy way
    to rollover passwords without increasing the risk of an application
    outage. After a password change, the users/admins have to rush to
    change the password in all locations where it is stored. There is a
    window of time where if the application password is not changed to the
    new one, and the application tries to connect/reconnect for any
    reason, the application will fail authentication and lead to an outage.
    
    I personally haven't seen any attempts by any
    application/driver/framework to solve this problem in the wild, so
    following is just me theorizing how one may solve this problem on the
    application side; there may be other ways in which others may solve
    this problem. The application may be written in such a way that upon
    password authentication failure, it tries again with a second
    password. The application's configuration file (or environment
    variables) may allow specifying 2 passwords at the same time, and the
    application will keep trying these 2 passwords alternatively until it
    succeeds or the user restarts it with a new configuration. With such a
    logic in place in their application, the users may first change the
    configuration of all the instances of the application to hold the new
    password along with the old/current working password, and only then
    change the password in the database. This way, in the event of an
    application instance start/restart either the old password will
    succeed, or the new password will.
    
    There may be other ways to solve this problem, but I can't imagine any
    of those ways to be convenient and straightforward. At least not as
    convenient as it can be if the database itself allowed for storing
    both the passwords, and honored both passwords at the same time, while
    allowing to associate a separate validity period with each of the
    passwords.
    
    The patches posted in this thread so far attempt to add the ability to
    allow the user to have an arbitrary number of passwords. I believe
    that allowing arbitrary number of passwords is not only unnecessary,
    but the need to name passwords, the need to store them in a shared
    catalog, etc. may actually create problems in the field. The
    users/admins will have to choose names for passwords, which they
    didn't have to previously. The need to name them may also lead to
    users storing password-hints in the password names (e.g. 'mom''s
    birthday', 'ex''s phone number', 'third password'), rendering the
    passwords weak.
    
    Moreover, allowing an arbitrarily many number of passwords will
    require us to provide additional infrastructure to solve problems like
    observability (which passwords are currently in use, and which ones
    have been effectively forgotten by applications), or create a nuisance
    for admins that can create more problems than it solves.
    
    So I propose that the feature should allow no more than 2 passwords
    for a role, each with their own validity periods. This eliminates the
    need to name passwords, because at any given time there are no more
    than 2 passwords; current one, and old one. This also eliminates the
    need for a shared catalog to hold passwords, because with the limit of
    2 imposed, we can store the old password and its validity period in
    additional columns in the pg_authid table.
    
    The patches so far also add a notion of max validity period of
    passwords, which only a superuser can override. I believe this is a
    useful feature, but that feature can be dealt with separately,
    independent of password rollover feature. So in the newer patches I
    will not include the relevant GUC and code.
    
    With the above being said, following is the user interface I can think
    of that can allow for various operations that users may need to
    perform to rollover their passwords. The 'ADD PASSWORD' and 'ALL
    PASSWORD' are additions to the grammar. rololdpassword and
    rololdvaliduntil will be new columns in pg_authid that will hold the
    old password and its valid-until value.
    
    In essence, we create a stack that can hold 2 passwords. Pushing an
    element when it's full will make it forget the bottom element. Popping
    the stack makes it forget the top element, and the only remaining
    element, if any, becomes the top.
    
    -- Create a user, as usual
    CREATE ROLE u1 PASSWORD 'p1' VALID UNTIL '2020/01/01';
    
    -- Add another password that the user can use for authentication. This moves
    -- the 'p1' password hash and its valid-until value to rololdpassword and
    -- rololdvaliduntil, respectively.
    ALTER ROLE u1 ADD PASSWORD 'p2' VALID UNTIL '2021/01/01';
    
    -- Change the password 'p2's (current password's) validity
    ALTER ROLE u1 VALID UNTIL '2022/01/01';
    -- Note that currently I don't have a proposal for how to change the old
    -- password's validity period, without deleting the latest/main password. See
    -- PASSWORD NULL command below on how to delete the current password. It's very
    -- likely that in a password rollover use case it's unnecessary, even
    -- undesirable, to change the old password's validity period.
    
    -- If, for some reason, the user wants to get rid of the latest password added.
    -- Remove 'p2' (current password). The old password (p1), will be restored to
    -- rolpassword, along with its valid-until value.
    ALTER ROLE u1 PASSWORD NULL;
    -- This may come as a surprise to some users, because currently they expect the
    -- user to completely lose the ability to use passwords for login after this
    -- command. To get the old behavior, the user must now use the ALL PASSWORD
    -- NULL incantation; see below.
    -- Issuing this command one more time will remove even the restored password,
    -- hence leaving the user with no passwords.
    
    -- Change the validity of the restored/current password (p1)
    ALTER ROLE u1 VALID UNTIL '2022/01/01';
    
    -- Add a new password (p3) without affecting old password's (p1) validity
    ALTER ROLE u1 ADD PASSWORD 'p3' VALID UNTIL '2023/01/01';
    
    -- Add a new password 'p4'. This will move 'p3' to rololdpassword, and hence
    -- 'p1' will be forgotten completely.
    -- After this command, user can use passwords 'p3' (old) and 'p4' (current) to
    -- login.
    ALTER ROLE u1 ADD PASSWORD 'p4' VALID UNTIL '2024/01/01';
    
    -- Replace 'p4' (current) password with 'p5'. Note that this command is _not_
    -- using the ADD keyword, hence 'p4' is _not_ moved to rololdpassword column.
    -- After this command, user can use passwords 'p3' (old) and 'p5'
    -- (current) to login.
    ALTER ROLE u1 PASSWORD 'p5' VALID UNTIL '2025/01/01';
    
    -- Using the old password to login will produce a warning, hopefully nudging
    -- the user to start using the new password.
    export PGPASSWORD=p3
    psql -U u1
    ...
    WARNING: Used old password to login
    
    export PGPASSWORD=p5
    psql -U u1
    ...
    => (no warning)
    
    -- Remove all passwords from the role. Even old password, if any, is removed.
    ALTER ROLE u1 ALL PASSWORD NULL;
    
    In normal use, the users can simply keep ADDing new passwords, and the
    database will promptly remember only one old password, and keep
    forgetting any passwords older than that. But on the off chance
    that someone needs to forget the latest password they added, and
    restore the old password to be the "current" password, they can use
    the PASSWORD NULL incantation. Note that this will result in
    rol*old*password being set to NULL, because our password memory stack
    cannot hold more than 2 elements.
    
    Since this feature is targeted towards password rollovers, it's a legitimate
    question to ask if we should enforce that the new password being added has a
    valid-until greater than the valid-until of the existing/old password. I don't
    think we should enforce this, at least not in this patch, because the
    user/admin may have a use case where they want a short-lived new password that
    they intend/want to change very soon; I'm thinking of cases where passwords are
    being rolled over while they are also moving from older clients/libraries that
    don't yet support scram-sha-256; keep using md5 and add passwords to honor
    password rollover policy, but then as soon as all clients have been updated and
    have the ability to use scram-sha-256, rollover the password again to utilize
    the better mechanism.
    
    I realize that allowing for a maximum of 2 passwords goes against the
    zero-one-infinity rule [1], but I think in the case of password
    rollovers it's perfectly acceptable to limit the number of active
    passwords to just 2. If there are use cases, either related to password
    rollovers, or in its vicinity, that can be better addressed by
    allowing an arbitrarily many passwords, I would love to learn about
    them and change this design to accommodate for those use cases, or
    perhaps revert to pursuing the multiple-passwords feature.
    
    [1]: https://en.wikipedia.org/wiki/Zero_one_infinity_rule
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
    
    
    
  14. Re: [PoC/RFC] Multiple passwords, interval expirations

    Nathan Bossart <nathandbossart@gmail.com> — 2023-10-05T19:04:53Z

    On Wed, Oct 04, 2023 at 10:41:15PM -0700, Gurjeet Singh wrote:
    > The patches posted in this thread so far attempt to add the ability to
    > allow the user to have an arbitrary number of passwords. I believe
    > that allowing arbitrary number of passwords is not only unnecessary,
    > but the need to name passwords, the need to store them in a shared
    > catalog, etc. may actually create problems in the field. The
    > users/admins will have to choose names for passwords, which they
    > didn't have to previously. The need to name them may also lead to
    > users storing password-hints in the password names (e.g. 'mom''s
    > birthday', 'ex''s phone number', 'third password'), rendering the
    > passwords weak.
    > 
    > Moreover, allowing an arbitrarily many number of passwords will
    > require us to provide additional infrastructure to solve problems like
    > observability (which passwords are currently in use, and which ones
    > have been effectively forgotten by applications), or create a nuisance
    > for admins that can create more problems than it solves.
    
    IMHO neither of these problems seems insurmountable.  Besides advising
    against using hints as names, we could also automatically generate safe
    names, or even disallow user-provided names entirely.  And adding
    observability for passwords seems worthwhile anyway.
    
    > So I propose that the feature should allow no more than 2 passwords
    > for a role, each with their own validity periods. This eliminates the
    > need to name passwords, because at any given time there are no more
    > than 2 passwords; current one, and old one. This also eliminates the
    > need for a shared catalog to hold passwords, because with the limit of
    > 2 imposed, we can store the old password and its validity period in
    > additional columns in the pg_authid table.
    
    Another approach could be to allow an abritrary number of passwords but to
    also allow administrators to limit how many passwords can be associated to
    each role.  That way, we needn't restrict this feature to 2 passwords for
    everyone.  Perhaps 2 should be the default, but in any case, IMO we
    shouldn't design to only support 2.
    
    > In essence, we create a stack that can hold 2 passwords. Pushing an
    > element when it's full will make it forget the bottom element. Popping
    > the stack makes it forget the top element, and the only remaining
    > element, if any, becomes the top.
    
    I think this would be mighty confusing to users since it's not clear that
    adding a password will potentially invalidate a current password (which
    might be actively in use), but only if there are already 2 in the stack.  I
    worry that such a desіgn might be too closely tailored to the
    implementation details.  If we proceed with this design, perhaps we should
    consider ERROR-ing if a user tries to add a third password.
    
    > -- If, for some reason, the user wants to get rid of the latest password added.
    > -- Remove 'p2' (current password). The old password (p1), will be restored to
    > -- rolpassword, along with its valid-until value.
    > ALTER ROLE u1 PASSWORD NULL;
    > -- This may come as a surprise to some users, because currently they expect the
    > -- user to completely lose the ability to use passwords for login after this
    > -- command. To get the old behavior, the user must now use the ALL PASSWORD
    > -- NULL incantation; see below.
    > -- Issuing this command one more time will remove even the restored password,
    > -- hence leaving the user with no passwords.
    
    Is it possible to remove the oldest password added without removing the
    latest password added?
    
    -- 
    Nathan Bossart
    Amazon Web Services: https://aws.amazon.com
    
    
    
    
  15. Re: [PoC/RFC] Multiple passwords, interval expirations

    Jeff Davis <pgsql@j-davis.com> — 2023-10-05T20:09:36Z

    On Thu, 2023-10-05 at 14:04 -0500, Nathan Bossart wrote:
    > IMHO neither of these problems seems insurmountable.  Besides
    > advising
    > against using hints as names, we could also automatically generate
    > safe
    > names, or even disallow user-provided names entirely.  
    
    I'd like to see what this looks like as a user-interface. Using a name
    seems weird because of the reasons Gurjeet mentioned.
    
    Using a number seems weird to me because either:
    
     (a) if the number is always increasing you'd have to look to find the
    number of the new slot to add and the old slot to remove; or
     (b) if switched between two numbers (say 0 and 1), it would be error
    prone because you'd have to remember which is the old one that can be
    safely replaced
    
    Maybe a password is best described by its validity period rather than a
    name? But what about passwords that don't expire?
    
    > And adding
    > observability for passwords seems worthwhile anyway.
    
    That might be useful just to know whether a user's password is even
    being used -- in case the admin makes a mistake and some other auth
    method is being used. Also it would help to know when a password can
    safely be removed.
    > 
    
    >   That way, we needn't restrict this feature to 2 passwords for
    > everyone.  Perhaps 2 should be the default, but in any case, IMO we
    > shouldn't design to only support 2.
    
    Are there use cases for lots of passwords, or is it just a matter of
    not introducing an artificial limitation?
    
    Would it ever make sense to have a role that has two permanent
    passwords, or would that be an abuse of this feature? Any use cases I
    can think of would be better solved with multiple user that are part of
    the same group.
    
    > 
    > I think this would be mighty confusing to users since it's not clear
    > that
    > adding a password will potentially invalidate a current password
    > (which
    > might be actively in use), but only if there are already 2 in the
    > stack.  I
    > worry that such a desіgn might be too closely tailored to the
    > implementation details.  If we proceed with this design, perhaps we
    > should
    > consider ERROR-ing if a user tries to add a third password.
    
    I agree that the proposed language is confusing, especially because ADD
    causes a password to be added and another one to be removed. But
    perhaps there are some non-confusing ways to expose a similar idea.
    
    The thing I like about Gurjeet's proposal is that it's well-targeted at
    a specific use case rather than trying to be too general. That makes it
    a little easier to avoid certain problems like having a process that
    adds passwords and never removes the old ones (leading to weird
    problems like 47000 passwords for one user).
    
    But it also feels strange to be limited to two -- perhaps the password
    rotation schedule or policy just doesn't work with a limit of two, or
    perhaps that introduces new kinds of mistakes.
    
    Another idea: what if we introduce the notion of deprecating a
    password? To remove a password, it would have to be deprecated first,
    and maybe that would cause a LOG or WARNING message to be emitted when
    used, or show up differently in some system view. And perhaps you could
    have at most one non-deprecated password. That would give a workflow
    something like (I'm not proposing these exact keywords):
    
      CREATE USER foo PASSWORD 'secret1';
      ALTER USER foo DEPRECATE PASSWORD; -- 'secret1' still works
      ALTER USER foo PASSWORD 'secret2'; -- 'secret1' or 'secret2' works
      ... fix some applications
      SET log_deprecated_password_use = WARNING;
    
      ...
      WARNING: deprecated password used for user 'foo'
      ... fix some applications you forgot about
      ... warnings quiet down
      ALTER USER foo DROP DEPRECATED PASSWORD; -- only 'secret2' works
    
    If the user wants to un-deprecate a password (before they drop it, of
    course), they can do something like:
    
      ALTER USER foo PASSWORD NULL; -- 'secret2' removed
      ALTER USER foo UNDEPRECATE PASSWORD; -- 'secret1' restored
    
    if we allow multiple deprecated passwords, we'd still have to come up
    with some way to address them (names, numbers, validity period,
    something). But by isolating the problem to deprecated passwords only,
    it feels like the system is still being restored to a clean state with
    at most one single current password. The awkwardness is contained to
    old passwords which will hopefully go away soon anyway and not
    represent permanent clutter.
    
    Regards,
    	Jeff Davis
    
    
    
    
    
  16. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-05T20:55:26Z

    On Thu, Oct 5, 2023 at 12:04 PM Nathan Bossart <nathandbossart@gmail.com> wrote:
    >
    > On Wed, Oct 04, 2023 at 10:41:15PM -0700, Gurjeet Singh wrote:
    > > The patches posted in this thread so far attempt to add the ability to
    > > allow the user to have an arbitrary number of passwords. I believe
    > > that allowing arbitrary number of passwords is not only unnecessary,
    > > but the need to name passwords, the need to store them in a shared
    > > catalog, etc. may actually create problems in the field. The
    > > users/admins will have to choose names for passwords, which they
    > > didn't have to previously. The need to name them may also lead to
    > > users storing password-hints in the password names (e.g. 'mom''s
    > > birthday', 'ex''s phone number', 'third password'), rendering the
    > > passwords weak.
    > >
    > > Moreover, allowing an arbitrarily many number of passwords will
    > > require us to provide additional infrastructure to solve problems like
    > > observability (which passwords are currently in use, and which ones
    > > have been effectively forgotten by applications), or create a nuisance
    > > for admins that can create more problems than it solves.
    >
    > IMHO neither of these problems seems insurmountable.
    
    Agreed.
    
    > Besides advising
    > against using hints as names, we could also automatically generate safe
    > names, or even disallow user-provided names entirely.
    
    Somehow naming passwords doesn't feel palatable to me.
    
    > And adding
    > observability for passwords seems worthwhile anyway.
    
    Agreed.
    
    > > So I propose that the feature should allow no more than 2 passwords
    > > for a role, each with their own validity periods. This eliminates the
    > > need to name passwords, because at any given time there are no more
    > > than 2 passwords; current one, and old one. This also eliminates the
    > > need for a shared catalog to hold passwords, because with the limit of
    > > 2 imposed, we can store the old password and its validity period in
    > > additional columns in the pg_authid table.
    >
    > Another approach could be to allow an abritrary number of passwords but to
    > also allow administrators to limit how many passwords can be associated to
    > each role.  That way, we needn't restrict this feature to 2 passwords for
    > everyone.  Perhaps 2 should be the default, but in any case, IMO we
    > shouldn't design to only support 2.
    
    I don't see a real use case to support more than 2 passwords. Allowing
    an arbitrary number of passwords might look good and clean from
    aesthetics and documentation perspective (no artificially enforced
    limits, as in the zero-one-infinity rule), but in absence of real use
    cases for that many passwords, I'm afraid we might end up with a
    feature that creates more and worse problems for the users than it
    solves.
    
    > > In essence, we create a stack that can hold 2 passwords. Pushing an
    > > element when it's full will make it forget the bottom element. Popping
    > > the stack makes it forget the top element, and the only remaining
    > > element, if any, becomes the top.
    >
    > I think this would be mighty confusing to users since it's not clear that
    > adding a password will potentially invalidate a current password (which
    > might be actively in use), but only if there are already 2 in the stack.
    
    Fair point. We can aid the user by emitting a NOTICE (or a WARNING)
    message whenever an old password is removed from the system because of
    addition of a new password.
    
    > I
    > worry that such a desіgn might be too closely tailored to the
    > implementation details.  If we proceed with this design, perhaps we should
    > consider ERROR-ing if a user tries to add a third password.
    
    I did not have a stack in mind when developing the use case and the
    grammar, so implementation details did not drive this design. This new
    design was more of a response to the manageability nightmare that I
    could see the old approach may lead to. When writing the email I
    thought mentioning the stack analogy may make it easier to develop a
    mental model. I certainly won't suggest using it in the docs for
    explanation :-)
    
    > > -- If, for some reason, the user wants to get rid of the latest password added.
    > > -- Remove 'p2' (current password). The old password (p1), will be restored to
    > > -- rolpassword, along with its valid-until value.
    > > ALTER ROLE u1 PASSWORD NULL;
    > > -- This may come as a surprise to some users, because currently they expect the
    > > -- user to completely lose the ability to use passwords for login after this
    > > -- command. To get the old behavior, the user must now use the ALL PASSWORD
    > > -- NULL incantation; see below.
    > > -- Issuing this command one more time will remove even the restored password,
    > > -- hence leaving the user with no passwords.
    >
    > Is it possible to remove the oldest password added without removing the
    > latest password added?
    
    In the patch I have so far, ALTER ROLE u1 ADD PASSWORD '' (empty
    string) will drop the old password (what you asked for), and move the
    current password to rololdpassword (which is not exactly what you
    asked for :-). Hence the oldest password will be forgotten, and the
    current password will continue to work;
    
    Perhaps an explicit syntax like ALTER ROLE u1 DROP OLD PASSWORD can be
    used for this.
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
    
    
    
  17. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-05T21:28:17Z

    On Thu, Oct 5, 2023 at 1:09 PM Jeff Davis <pgsql@j-davis.com> wrote:
    >
    > >
    > > I think this would be mighty confusing to users since it's not clear
    > > that
    > > adding a password will potentially invalidate a current password
    > > (which
    > > might be actively in use), but only if there are already 2 in the
    > > stack.  I
    > > worry that such a desіgn might be too closely tailored to the
    > > implementation details.  If we proceed with this design, perhaps we
    > > should
    > > consider ERROR-ing if a user tries to add a third password.
    >
    > I agree that the proposed language is confusing, especially because ADD
    > causes a password to be added and another one to be removed. But
    > perhaps there are some non-confusing ways to expose a similar idea.
    
    How about a language like the following (I haven't tried if this will
    work in the grammar we have):
    
    CREATE ROLE u1 PASSWORD 'p1';
    
    ALTER ROLE u1ADD NEW PASSWORD 'p2';
    
    ALTER ROLE u1 ADD NEW PASSOWRD 'p3';
    ERROR: Cannot have more than 2 passwords at the same time.
    
    ALTER ROLE u1 DROP OLD PASSWORD;
    
    ALTER ROLE u1 ADD NEW PASSOWRD 'p3';
    -- succeeds; forgets password 'p1'; p2 and p3 can be used to login
    
    ALTER ROLE u1 DROP NEW PASSWORD;
    -- forgets password 'p3'. Only 'p2' can be used to login
    
    ALTER ROLE u1 ADD NEW PASSOWRD 'p4';
    -- succeeds; 'p2' and 'p4' can be used to login
    
    -- Set the valid-until of 'new' (p4) password
    ALTER ROLE u1 VALID UNTIL '2024/01/01';
    
    -- If we need the ability to change valid-until of both old and new,
    we may allow something like the following.
    ALTER ROLE u1 [_NEW_ | OLD] VALID UNTIL '2024/01/01';
    
    This way there's a notion of a 'new' and 'old' passwords. User cannot
    add a third password without explicitly dropping one of existing
    passwords (either old or new). At any time the user can choose to drop
    the old or the new password. Adding a new password will mark the
    current password as 'old'; if there's only old password (because 'new'
    was dropped) the 'old' password will remain intact and the new one
    will be placed in 'current'/new spot.
    
    So in normal course of operation, even for automated jobs, the
    expected flow to roll over the passwords would be:
    
    ALTER USER u1 DROP OLD PASSWORD;
    -- success if there is an old password; otherwise NOTICE: no old password
    ALTER USER u1 ADD NEW PASSWORD 'new-secret';
    
    > The thing I like about Gurjeet's proposal is that it's well-targeted at
    > a specific use case rather than trying to be too general. That makes it
    > a little easier to avoid certain problems like having a process that
    > adds passwords and never removes the old ones (leading to weird
    > problems like 47000 passwords for one user).
    >
    > But it also feels strange to be limited to two -- perhaps the password
    > rotation schedule or policy just doesn't work with a limit of two, or
    > perhaps that introduces new kinds of mistakes.
    >
    > Another idea: what if we introduce the notion of deprecating a
    > password?
    
    I'll have to think more about it, but perhaps my above proposal
    addresses the use case you describe.
    
    > if we allow multiple deprecated passwords, we'd still have to come up
    > with some way to address them (names, numbers, validity period,
    > something). But by isolating the problem to deprecated passwords only,
    > it feels like the system is still being restored to a clean state with
    > at most one single current password. The awkwardness is contained to
    > old passwords which will hopefully go away soon anyway and not
    > represent permanent clutter.
    
    +1
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
    
    
    
  18. Re: [PoC/RFC] Multiple passwords, interval expirations

    Nathan Bossart <nathandbossart@gmail.com> — 2023-10-06T19:26:31Z

    On Thu, Oct 05, 2023 at 01:09:36PM -0700, Jeff Davis wrote:
    > On Thu, 2023-10-05 at 14:04 -0500, Nathan Bossart wrote:
    >> That way, we needn't restrict this feature to 2 passwords for
    >> everyone.  Perhaps 2 should be the default, but in any case, IMO we
    >> shouldn't design to only support 2.
    > 
    > Are there use cases for lots of passwords, or is it just a matter of
    > not introducing an artificial limitation?
    
    I guess it's more of the latter.  Perhaps one potential use case would be
    short-lived credentials that are created on demand.  Such a password might
    only be valid for something like 15 minutes, and many users might have the
    ability to request a password for the database role.  I don't know whether
    there is a ton of demand for such a use case, and it might already be
    solvable by just creating separate roles.  In any case, if there's general
    agreement that we only want to target the rotation use case, that's fine by
    me.
    
    -- 
    Nathan Bossart
    Amazon Web Services: https://aws.amazon.com
    
    
    
    
  19. Re: [PoC/RFC] Multiple passwords, interval expirations

    Jeff Davis <pgsql@j-davis.com> — 2023-10-06T20:20:03Z

    On Fri, 2023-10-06 at 14:26 -0500, Nathan Bossart wrote:
    > I guess it's more of the latter.  Perhaps one potential use case
    > would be
    > short-lived credentials that are created on demand.  Such a password
    > might
    > only be valid for something like 15 minutes, and many users might
    > have the
    > ability to request a password for the database role.  I don't know
    > whether
    > there is a ton of demand for such a use case, and it might already be
    > solvable by just creating separate roles.  In any case, if there's
    > general
    > agreement that we only want to target the rotation use case, that's
    > fine by
    > me.
    
    The basic problem, as I see it, is: how do we keep users from
    accidentally dropping the wrong password? Generated unique names or
    numbers don't solve that problem. Auto-incrementing or a created-at
    timestamp solves it in the sense that you can at least look at a system
    view and see if there's a newer one, but it's a little awkward. A
    validity period is a good fit if all passwords have a validity period
    and we don't change it, but gets awkward otherwise.
    
    I'm also worried about two kinds of clutter:
    
    * old passwords not being garbage-collected
    * the identifier of the current password always changing (perhaps fine
    if it'a a "created at" ID?)
    
    Regards,
    	Jeff Davis
    
    
    
    
    
  20. Re: [PoC/RFC] Multiple passwords, interval expirations

    Jeff Davis <pgsql@j-davis.com> — 2023-10-06T20:29:24Z

    On Thu, 2023-10-05 at 14:28 -0700, Gurjeet Singh wrote:
    
    > This way there's a notion of a 'new' and 'old' passwords.
    
    IIUC, you are proposing that there are exactly two slots, NEW and OLD.
    When adding a password, OLD must be unset and it moves NEW to OLD, and
    adds the new password in NEW. DROP only works on OLD. Is that right?
    
    It's close to the idea of deprecation, except that adding a new
    password implicitly deprecates the existing one. I'm not sure about
    that -- it could be confusing.
    
    We could also try using a verb like "expire" that could be coupled with
    a date, and that way all old passwords would always have some validity
    period. That might make it a bit easier to manage if we do need more
    than two passwords.
    
    Regards,
    	Jeff Davis
    
    
    
    
    
  21. Re: [PoC/RFC] Multiple passwords, interval expirations

    Bruce Momjian <bruce@momjian.us> — 2023-10-06T20:46:01Z

    On Fri, Oct  6, 2023 at 01:20:03PM -0700, Jeff Davis wrote:
    > The basic problem, as I see it, is: how do we keep users from
    > accidentally dropping the wrong password? Generated unique names or
    
    I thought we could auto-remove old password if the valid-until date is
    in the past.  You would need a separate ALTER command to sets its date
    in the past without that.  Also, defining a new password could require
    setting the expiration date of the old password to make future additions
    easier.
    
    For pg_authid, I was thinking of columns:
    
    	ADD	rolpassword_old
    	ADD	rolvaliduntil_old
    	EXISTS	rolpassword
    	EXISTS	rolvaliduntil
    
    I did blog about the password rotation problem and suggested
    certificates:
    
    	https://momjian.us/main/blogs/pgblog/2020.html#July_17_2020
    
    -- 
      Bruce Momjian  <bruce@momjian.us>        https://momjian.us
      EDB                                      https://enterprisedb.com
    
      Only you can decide what is important to you.
    
    
    
    
  22. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-08T17:24:42Z

    On Fri, Oct 6, 2023 at 1:46 PM Bruce Momjian <bruce@momjian.us> wrote:
    >
    > On Fri, Oct  6, 2023 at 01:20:03PM -0700, Jeff Davis wrote:
    > > The basic problem, as I see it, is: how do we keep users from
    > > accidentally dropping the wrong password? Generated unique names or
    >
    > I thought we could auto-remove old password if the valid-until date is
    > in the past.
    
    Autoremoving expired passwords will surprise users, and not in a good
    way. Making a password, even an expired one, disappear from the system
    will lead to astonishment. Among uses of an expired password are cases
    of it acting like a tombstone, and the case where the user may want to
    extend the validity of a password, instead of having to create a new
    one and change application configuration(s) to specify the new
    password.
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
    
    
    
  23. Re: [PoC/RFC] Multiple passwords, interval expirations

    Bruce Momjian <bruce@momjian.us> — 2023-10-08T17:29:14Z

    On Sun, Oct  8, 2023 at 10:24:42AM -0700, Gurjeet Singh wrote:
    > On Fri, Oct 6, 2023 at 1:46 PM Bruce Momjian <bruce@momjian.us> wrote:
    > >
    > > On Fri, Oct  6, 2023 at 01:20:03PM -0700, Jeff Davis wrote:
    > > > The basic problem, as I see it, is: how do we keep users from
    > > > accidentally dropping the wrong password? Generated unique names or
    > >
    > > I thought we could auto-remove old password if the valid-until date is
    > > in the past.
    > 
    > Autoremoving expired passwords will surprise users, and not in a good
    > way. Making a password, even an expired one, disappear from the system
    > will lead to astonishment. Among uses of an expired password are cases
    > of it acting like a tombstone, and the case where the user may want to
    > extend the validity of a password, instead of having to create a new
    > one and change application configuration(s) to specify the new
    > password.
    
    I was speaking of autoremoving in cases where we are creating a new one,
    and taking the previous new one and making it the old one, if that was
    not clear.
    
    -- 
      Bruce Momjian  <bruce@momjian.us>        https://momjian.us
      EDB                                      https://enterprisedb.com
    
      Only you can decide what is important to you.
    
    
    
    
  24. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-08T17:50:15Z

    On Sun, Oct 8, 2023 at 10:29 AM Bruce Momjian <bruce@momjian.us> wrote:
    >
    > I was speaking of autoremoving in cases where we are creating a new one,
    > and taking the previous new one and making it the old one, if that was
    > not clear.
    
    Yes, I think I understood it differently. I understood it to mean that
    this behaviour would apply to all passwords, those created by existing
    commands, as well as to those created by new commands for rollover use
    case. Whereas you meant this autoremove behaviour to apply only to
    those passwords created by/for rollover related commands. I hope I've
    understood your proposal correctly this time around :-)
    
    I believe the passwords created by rollover feature should
    behave by the same rules as the rules for passwords created by
    existing CREATE/ALTER ROLE commands. If we implement the behaviour to
    delete expired passwords, then I believe that behaviour should apply
    to all passwords, irrespective of which command/feature was used to
    create a password.
    
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
    
    
    
  25. Re: [PoC/RFC] Multiple passwords, interval expirations

    Bruce Momjian <bruce@momjian.us> — 2023-10-08T18:55:19Z

    On Sun, Oct  8, 2023 at 10:50:15AM -0700, Gurjeet Singh wrote:
    > On Sun, Oct 8, 2023 at 10:29 AM Bruce Momjian <bruce@momjian.us> wrote:
    > >
    > > I was speaking of autoremoving in cases where we are creating a new one,
    > > and taking the previous new one and making it the old one, if that was
    > > not clear.
    > 
    > Yes, I think I understood it differently. I understood it to mean that
    > this behaviour would apply to all passwords, those created by existing
    > commands, as well as to those created by new commands for rollover use
    > case. Whereas you meant this autoremove behaviour to apply only to
    > those passwords created by/for rollover related commands. I hope I've
    > understood your proposal correctly this time around :-)
    
    Yes, it is only during the addition of a new password when the previous
    new password becomes the new old password.  The previous old password
    would need to have an rolvaliduntil in the past.
    
    > I believe the passwords created by rollover feature should
    > behave by the same rules as the rules for passwords created by
    > existing CREATE/ALTER ROLE commands. If we implement the behaviour to
    > delete expired passwords, then I believe that behaviour should apply
    > to all passwords, irrespective of which command/feature was used to
    > create a password.
    
    This would only apply when we are moving the previous new password to
    old and the old one is removed.
    
    -- 
      Bruce Momjian  <bruce@momjian.us>        https://momjian.us
      EDB                                      https://enterprisedb.com
    
      Only you can decide what is important to you.
    
    
    
    
  26. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-08T20:01:00Z

    On Fri, Oct 6, 2023 at 1:29 PM Jeff Davis <pgsql@j-davis.com> wrote:
    >
    > On Thu, 2023-10-05 at 14:28 -0700, Gurjeet Singh wrote:
    >
    > > This way there's a notion of a 'new' and 'old' passwords.
    >
    > IIUC, you are proposing that there are exactly two slots, NEW and OLD.
    > When adding a password, OLD must be unset and it moves NEW to OLD, and
    > adds the new password in NEW. DROP only works on OLD. Is that right?
    
    Yes, that's what I was proposing. But thinking a bit more about it,
    the _implicit_ shuffling of labels 'new' and 'old' doesn't feel right
    to me. The password that used to be referred to as 'new' now
    automatically gets labeled 'old'.
    
    > It's close to the idea of deprecation, except that adding a new
    > password implicitly deprecates the existing one. I'm not sure about
    > that -- it could be confusing.
    
    +1
    
    > We could also try using a verb like "expire" that could be coupled with
    > a date, and that way all old passwords would always have some validity
    > period.
    
    Forcing the users to pick an expiry date for a password they intend to
    rollover, when an expiry date did not exist before for that password,
    feels like adding more burden to their password rollover decision
    making. The dates and rules of password rollover may be a part of a
    system external to their database, (wiki, docs, calendar, etc.) which
    now they will be forced to translate into a timestamp to specify in
    the rollover commands.
    
    I believe we should fix the _names_ of the slots the 2 passwords are
    stored in, and provide commands that manipulate those slots by
    respective names; the commands should not implicitly move the
    passwords between the slots. Additionally, we may provide functions
    that provide observability info for these slots. I propose the slot
    names FIRST and SECOND (I picked these because these keywords/tokens
    already exist in the grammar, but not yet sure if the grammar rules
    would allow their use; feel free to propose better names). FIRST
    refers to the the existing slot, namely rolpassword. SECOND refers to
    the new slot we'd add, that is, a pgauthid column named
    rolsecondpassword. The existing commands, or when neither FIRST nor
    SECOND are specified, the commands apply to the existing slot, a.k.a.
    FIRST.
    
    The user interface might look like the following:
    
    -- Create a user, as usual
    CREATE ROLE u1 PASSWORD 'p1' VALID UNTIL '2020/01/01';
    -- This automatically occupies the 'first' slot
    
    -- Add another password that the user can use for authentication.
    ALTER ROLE u1 ADD SECOND PASSWORD 'p2' VALID UNTIL '2021/01/01';
    
    -- Change both the passwords' validity independently; this solves the
    -- problem with the previous '2-element stack' approach, where we
    -- could not address the password at the bottom of the stack.
    ALTER ROLE u1 SECOND PASSWORD VALID UNTIL '2022/01/01';
    
    ALTER ROLE u1 [ [ FIRST ] PASSWORD ] VALID UNTIL '2022/01/01';
    
    -- If, for some reason, the user wants to get rid of the latest password added.
    ALTER ROLE u1 DROP SECOND PASSWORD;
    
    -- Add a new password (p3) in 'second' slot
    ALTER ROLE u1 ADD SECOND PASSWORD 'p3' VALID UNTIL '2023/01/01';
    
    -- Attempting to add a password while the respective slot is occupied
    -- results in error
    ALTER ROLE u1 ADD [ [ FIRST ] PASSWORD ] 'p4' VALID UNTIL '2024/01/01';
    ERROR: first password already exists
    
    ALTER ROLE u1 ADD SECOND PASSWORD 'p4' VALID UNTIL '2024/01/01';
    ERROR: second password already exists
    
    -- Users can use this function to check whether a password slot is occupied
    => select password_exists('u1', 'first');
    password_exists
    -----
    t
    
    => select password_exists('u1', 'second');
    password_exists
    -----
    t
    
    -- Remove all passwords from the role. Both, 'first' and 'second',
    passwords are removed.
    ALTER ROLE u1 DROP ALL PASSWORD;
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
    
    
    
  27. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-09T09:31:30Z

    On Sun, Oct 8, 2023 at 1:01 PM Gurjeet Singh <gurjeet@singh.im> wrote:
    >
    > On Fri, Oct 6, 2023 at 1:29 PM Jeff Davis <pgsql@j-davis.com> wrote:
    > >
    > > On Thu, 2023-10-05 at 14:28 -0700, Gurjeet Singh wrote:
    > >
    > > > This way there's a notion of a 'new' and 'old' passwords.
    > >
    > > IIUC, you are proposing that there are exactly two slots, NEW and OLD.
    > > When adding a password, OLD must be unset and it moves NEW to OLD, and
    > > adds the new password in NEW. DROP only works on OLD. Is that right?
    >
    > Yes, that's what I was proposing. But thinking a bit more about it,
    > the _implicit_ shuffling of labels 'new' and 'old' doesn't feel right
    > to me. The password that used to be referred to as 'new' now
    > automatically gets labeled 'old'.
    >
    > > It's close to the idea of deprecation, except that adding a new
    > > password implicitly deprecates the existing one. I'm not sure about
    > > that -- it could be confusing.
    >
    > +1
    
    > I believe we should fix the _names_ of the slots the 2 passwords are
    > stored in, and provide commands that manipulate those slots by
    > respective names; the commands should not implicitly move the
    > passwords between the slots. Additionally, we may provide functions
    > that provide observability info for these slots. I propose the slot
    > names FIRST and SECOND (I picked these because these keywords/tokens
    > already exist in the grammar, but not yet sure if the grammar rules
    > would allow their use; feel free to propose better names). FIRST
    > refers to the the existing slot, namely rolpassword. SECOND refers to
    > the new slot we'd add, that is, a pgauthid column named
    > rolsecondpassword. The existing commands, or when neither FIRST nor
    > SECOND are specified, the commands apply to the existing slot, a.k.a.
    > FIRST.
    
    Please see attached the patch that implements this proposal. The patch
    is named password_rollover_v3.diff, breaking from the name
    'multiple_passwords...', since this patch limits itself to address the
    password-rollover feature.
    
    The multiple_password* series of patches had removed a critical
    functionality, which I believe is crucial from security perspective.
    When a user does not exist, or has no passwords, or has passwords that
    have expired, we must pretend to perform authentication (network
    packet exchanges) as normally as possible, so that the absence of
    user, or lack of (or expiration of) passwords is not revealed to an
    attacker. I have restored the original behaviour in the
    CheckPWChallengeAuth() function; see commit aba99df407 [2].
    
    I looked for any existing keywords that may better fit the purpose of
    naming the slots, better than FIRST and SECOND, but I could not find
    any. Instead of DROP to remove the passwords, I tried DELETE and the
    grammar/bison did not complain about it; so DELETE is an option, too,
    but I feel DROP FIRST/SECOND/ALL PASSWORD is a better companion of ADD
    FIRST/SECOND PASSWORD syntax, in the same vein as ADD/DROP COLUMN.
    
    The doc changes are still missing, but the regression tests and the
    comments therein should provide a good idea of the user interface of
    this new feature. Documenting this behaviour in a succinct manner
    feels difficult; so ideas welcome for how to inform the reader that
    now a role is accompanied by two slots to store the passwords, and
    that the old commands operate on the first slot, and to operate on the
    second password slot one must use the new syntax. I guess it would be
    best to start the relevant section with "To support gradual password
    rollovers, Postgres provides the ability to store 2 active passwords
    at the same time. The passwords are referred to as FIRST and SECOND
    password. Each of these passwords can be changed independently, and
    each of these can have an associated expiration time, if necessary."
    
    Since these new commands are only available to ALTER ROLE (and not to
    CREATE ROLE), the corresponding command doc page also needs to be
    updated.
    
    Next steps:
    - Break the patch into a series of smaller patches.
    - Add TAP tests (test the ability to actually login with these passwords)
    - Add/update documentation
    - Add more regression tests
    
    The patch progress can be followed on the Git branch
    password_rollover_v3 [1]. This branch begins uses
    multiple_passwords_v4 as starting point, and removes unnecessary code
    (commit 326f60225f [3])
    
    The v1 (and tombstone of v2) patches of password_rollover never
    finished as the consensus changed while they were in progress, but
    they exist as sibling branches of the v3 branch.
    
    [1]: https://github.com/gurjeet/postgres/commits/password_rollover_v3
    [2]: https://github.com/gurjeet/postgres/commit/aba99df407a523357db2813f0eea0b45dbeb6006
    [3]: https://github.com/gurjeet/postgres/commit/326f60225f0e660338fc9c276c8728dc10db435b
    
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
  28. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-09T19:53:39Z

    On Mon, Oct 9, 2023 at 2:31 AM Gurjeet Singh <gurjeet@singh.im> wrote:
    >
    > Next steps:
    > - Break the patch into a series of smaller patches.
    
    Please see attached the same v3 patch, but now split into 3 separate
    patches. Each patch in the series depends on the previous patch to
    have been applied. I have made sure that each patch passes `make
    check` individually.
    
    First patch adds the two new columns, rolsecondpassword and
    rolsecondvaliduntil to the pg_authid shared catalog. This patch also
    updates the corresponding pg_authid.dat file to set these values to
    null for the rows populated during bootstrap. Finally, it adds code to
    CreateRole() to set these columns' values to NULL for a role being
    created.
    
    The second patch updates the password extraction, verification
    functions as well as authentication functions to honor the second
    password, if any. There is more detailed description in the commit
    message/body of the patch.
    
    The third patch adds the SQL support to the ALTER ROLE command which
    allows manipulation of both, the rolpassword and rolsecondpassword,
    columns and their respective expiration timestamps,
    rol[second]validuntil. This patch also adds regression tests for the
    new SQL command, demonstrating the use of the new grammar.
    
    v3-0001-Add-new-columns-to-pg_authid.patch
    v3-0002-Update-password-verification-infrastructure-to-ha.patch
    v3-0003-Added-SQL-support-for-ALTER-ROLE-to-manage-two-pa.patch
    
    
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
  29. Re: [PoC/RFC] Multiple passwords, interval expirations

    Gurjeet Singh <gurjeet@singh.im> — 2023-10-10T11:03:15Z

    > On Mon, Oct 9, 2023 at 2:31 AM Gurjeet Singh <gurjeet@singh.im> wrote:
    > >
    > > Next steps:
    > > - Break the patch into a series of smaller patches.
    > > - Add TAP tests (test the ability to actually login with these passwords)
    > > - Add/update documentation
    > > - Add more regression tests
    
    Please see attached the v4 of the patchset that introduces the notion
    of named passwords slots, namely 'first' and 'second' passwords, and
    allows users to address each of these passwords separately for the
    purposes of adding, dropping, or assigning expiration times.
    
    Apart from the changes described by each patch's commit title, one
    significant change since v3 is that now (included in v4-0002...patch)
    it is not allowed for a role to have a mix of a types of passwords.
    When adding a password, the patch ensures that the password being
    added uses the same hashing algorithm (md5 or scram-sha-256) as the
    existing password, if any.  Having all passwords of the same type
    helps the server pick the corresponding authentication method during
    connection attempt.
    
    The v3 patch also had a few bugs that were exposed by cfbot's
    automatic run. All those bugs have now been fixed, and the latest run
    on the v4 branch [1] on my private Git repo shows a clean run [1].
    
    The list of patches, and their commit titles are as follows:
    
    > v4-0001-...patch Add new columns to pg_authid
    > v4-0002-...patch Update password verification infrastructure to handle two passwords
    > v4-0003-...patch Added SQL support for ALTER ROLE to manage two passwords
    > v4-0004-...patch Updated pg_dumpall to support exporting a role's second password
    > v4-0005-...patch Update system views pg_roles and pg_shadow
    > v4-0006-...patch Updated pg_authid catalog documentation
    > v4-0007-...patch Updated psql's describe-roles meta-command
    > v4-0008-...patch Added documentation for ALTER ROLE command
    > v4-0009-...patch Added TAP tests to prove that a role can use two passwords to login
    > v4-0010-...patch pgindent run
    > v4-0011-...patch Run pgperltidy on files changed by this patchset
    
    Running pgperltidy updated many perl files unrelated to this patch, so
    in the last patch I chose to include only the one perl file that is
    affected by this patchset.
    
    [1]: password_rollover_v4 (910f81be54)
    https://github.com/gurjeet/postgres/commits/password_rollover_v4
    
    [2]: https://cirrus-ci.com/build/4675613999497216
    
    Best regards,
    Gurjeet
    http://Gurje.et
    
  30. Re: [PoC/RFC] Multiple passwords, interval expirations

    Stephen Frost <sfrost@snowman.net> — 2023-10-17T20:20:58Z

    Greetings,
    
    * Nathan Bossart (nathandbossart@gmail.com) wrote:
    > On Wed, Oct 04, 2023 at 10:41:15PM -0700, Gurjeet Singh wrote:
    > > The patches posted in this thread so far attempt to add the ability to
    > > allow the user to have an arbitrary number of passwords. I believe
    > > that allowing arbitrary number of passwords is not only unnecessary,
    > > but the need to name passwords, the need to store them in a shared
    > > catalog, etc. may actually create problems in the field. The
    > > users/admins will have to choose names for passwords, which they
    > > didn't have to previously. The need to name them may also lead to
    > > users storing password-hints in the password names (e.g. 'mom''s
    > > birthday', 'ex''s phone number', 'third password'), rendering the
    > > passwords weak.
    > > 
    > > Moreover, allowing an arbitrarily many number of passwords will
    > > require us to provide additional infrastructure to solve problems like
    > > observability (which passwords are currently in use, and which ones
    > > have been effectively forgotten by applications), or create a nuisance
    > > for admins that can create more problems than it solves.
    > 
    > IMHO neither of these problems seems insurmountable.  Besides advising
    > against using hints as names, we could also automatically generate safe
    > names, or even disallow user-provided names entirely.  And adding
    > observability for passwords seems worthwhile anyway.
    
    Agreed, particularly on adding observability for password use.
    Regardless of what we do, I feel pretty strongly that we need that.
    That said, having this handled in a separate catalog feels like a just
    generally better idea than shoving it all into pg_authid as we extend
    things to include information like "last used date", "last used source
    IP", etc.
    
    Providing this observability purely through logging strikes me as a
    terrible idea.
    
    I don't find the concern about names as 'hints' to be at all compelling.
    Having a way to avoid having names may have some value, but only if we
    can come up with something reasonable.
    
    > > So I propose that the feature should allow no more than 2 passwords
    > > for a role, each with their own validity periods. This eliminates the
    > > need to name passwords, because at any given time there are no more
    > > than 2 passwords; current one, and old one. This also eliminates the
    > > need for a shared catalog to hold passwords, because with the limit of
    > > 2 imposed, we can store the old password and its validity period in
    > > additional columns in the pg_authid table.
    > 
    > Another approach could be to allow an abritrary number of passwords but to
    > also allow administrators to limit how many passwords can be associated to
    > each role.  That way, we needn't restrict this feature to 2 passwords for
    > everyone.  Perhaps 2 should be the default, but in any case, IMO we
    > shouldn't design to only support 2.
    
    Agreed that it's a bad idea to design to support 2 and only 2.  If
    nothing else, there's the very simple case that the user needs to do
    another password rotation ... and they look and discover that the old
    password is still being used and that if they took it away, things would
    break, but they need time to run down which system is still using it
    while still needing to perform the migration for the other systems that
    are correctly being updated- boom, need 3 for that case.  There's other
    use-cases that could be interesting though- presumably we'd log which
    password is used to authenticate and then users could have a fleet of
    web servers which each have their own password but log into the same PG
    user and they could happily rotate the passwords independently for all
    of those systems.
    
    I don't propose this as some use-case just for the purpose of argument-
    not sharing passwords across a bunch of systems is absolutely a good
    stance when it comes to security, and due to the way permissions and
    roles work in PG, being able to have both distinct passwords with
    explicitly logged indication of which system used what password to log
    in while not having to deal with possibly permission differences due to
    using actually independent roles is valuable.  That is, each server
    using a separate role to log in could lead to some servers having access
    to something or other while others don't pretty easily- if they're all
    logging in with the same role and just a different password, that's not
    going to happen.
    
    * Jeff Davis (pgsql@j-davis.com) wrote:
    > Using a number seems weird to me because either:
    > 
    >  (a) if the number is always increasing you'd have to look to find the
    > number of the new slot to add and the old slot to remove; or
    >  (b) if switched between two numbers (say 0 and 1), it would be error
    > prone because you'd have to remember which is the old one that can be
    > safely replaced
    
    Yeah, a number doesn't strike me as very good either.
    
    > Maybe a password is best described by its validity period rather than a
    > name? But what about passwords that don't expire?
    
    The validity idea is interesting but falls down when you want multiple
    passwords that have the same validity period (or which all don't have
    any expiration).
    
    Giving users the option of not having to specify a name and letting the
    system come up with one (similar to what we do for indexes and such)
    could work out pretty decently, imv.  I'd have that be optional though-
    if the user wants to specify a name, then they should be allowed to do
    so.
    
    > > And adding
    > > observability for passwords seems worthwhile anyway.
    > 
    > That might be useful just to know whether a user's password is even
    > being used -- in case the admin makes a mistake and some other auth
    > method is being used. Also it would help to know when a password can
    > safely be removed.
    
    Yup, +100 on this.
    
    > Another idea: what if we introduce the notion of deprecating a
    > password? To remove a password, it would have to be deprecated first,
    > and maybe that would cause a LOG or WARNING message to be emitted when
    > used, or show up differently in some system view. And perhaps you could
    > have at most one non-deprecated password. That would give a workflow
    > something like (I'm not proposing these exact keywords):
    
    I don't see logs or warnings as being at all useful for this kind of
    thing.  Making it available through a view would work- but I don't think
    we need to go into the deprecation language ourselves as part of the
    grammer and instead should let users write their own queries against the
    views we provide to see what passwords are being used and what aren't.
    
    * Nathan Bossart (nathandbossart@gmail.com) wrote:
    > On Thu, Oct 05, 2023 at 01:09:36PM -0700, Jeff Davis wrote:
    > > On Thu, 2023-10-05 at 14:04 -0500, Nathan Bossart wrote:
    > >> That way, we needn't restrict this feature to 2 passwords for
    > >> everyone.  Perhaps 2 should be the default, but in any case, IMO we
    > >> shouldn't design to only support 2.
    > > 
    > > Are there use cases for lots of passwords, or is it just a matter of
    > > not introducing an artificial limitation?
    > 
    > I guess it's more of the latter.  Perhaps one potential use case would be
    > short-lived credentials that are created on demand.  Such a password might
    > only be valid for something like 15 minutes, and many users might have the
    > ability to request a password for the database role.  I don't know whether
    > there is a ton of demand for such a use case, and it might already be
    > solvable by just creating separate roles.  In any case, if there's general
    > agreement that we only want to target the rotation use case, that's fine by
    > me.
    
    Agreed, this seems like another good example of why we shouldn't design
    this for just 2.
    
    * Jeff Davis (pgsql@j-davis.com) wrote:
    > The basic problem, as I see it, is: how do we keep users from
    > accidentally dropping the wrong password? Generated unique names or
    > numbers don't solve that problem. Auto-incrementing or a created-at
    > timestamp solves it in the sense that you can at least look at a system
    > view and see if there's a newer one, but it's a little awkward. A
    > validity period is a good fit if all passwords have a validity period
    > and we don't change it, but gets awkward otherwise.
    
    Providing admins a way of seeing which passwords have been recently used
    seems like a clear way to minimize, at least, the risk of the wrong
    password being dropped.  Allowing them to control the name feels like
    it's another good way to minimize the risk since it's something they can
    define and they can include in the name whatever info they need to
    figure out if it's the one that's no longer being used, or not.  Forcing
    the use of numbers or of validation periods seems like it'd make it
    harder on users to avoid this risk, not easier.
    
    Allowing per-password expiration is another way to address the issue of
    the wrong password being removed by essentially taking the password away
    and seeing what breaks while having an easy way to bring it back if
    something important stops working.
    
    > I'm also worried about two kinds of clutter:
    > 
    > * old passwords not being garbage-collected
    
    I'm not terribly concerned with this if the password's validity has
    passed and therefore it can't be used any longer.  I could agree with
    the concern about it being an issue if the passwords all stay valid
    forever.  I'll point out that we arguably have this problem with roles
    already today and it doesn't seem to be a huge issue- PG has no idea how
    long that user is actually valid for, the admin needs to have something
    external to PG to deal with this.
    
    > * the identifier of the current password always changing (perhaps fine
    > if it'a a "created at" ID?)
    
    I'm not following what the issue is you're getting at here.
    
    Thanks,
    
    Stephen
    
  31. Re: [PoC/RFC] Multiple passwords, interval expirations

    Jeff Davis <pgsql@j-davis.com> — 2023-10-17T23:40:45Z

    On Tue, 2023-10-17 at 16:20 -0400, Stephen Frost wrote:
    > Agreed that it's a bad idea to design to support 2 and only 2.
    
    I don't disagree, but it's difficult to come up with syntax that:
    
     (a) supports N passwords
     (b) makes the ordinary cases simple and documentable
     (c) helps users avoid mistakes (at least in the simple cases)
     (d) makes sense passwords with and without validity period
     (e) handles the challenging cases
    
    One challenging case is that we cannot allow the mixing of password
    protocols (e.g. MD5 & SCRAM), because the authentication exchange only
    gets one chance at success. If someone ends up with 7 MD5 passwords,
    and they'd like to migrate to SCRAM, then we can't allow them to
    migrate one password at a time (because then the other passwords would
    break). I'd like to see what the SQL for doing this should look like.
    
    >   If
    > nothing else, there's the very simple case that the user needs to do
    > another password rotation ... and they look and discover that the old
    > password is still being used and that if they took it away, things
    > would
    > break, but they need time to run down which system is still using it
    > while still needing to perform the migration for the other systems
    > that
    > are correctly being updated- boom, need 3 for that case.
    
    That sounds like a reasonable use case. I don't know if we should make
    it a requirement, but if we come up with something reasonable that
    supports this case I'm fine with it. Ideally, it would still be easy to
    see when you are making a mistake (e.g. forgetting to ever remove
    passwords).
    
    >   There's other
    > use-cases that could be interesting though- presumably we'd log which
    > password is used to authenticate and then users could have a fleet of
    > web servers which each have their own password but log into the same
    > PG
    > user and they could happily rotate the passwords independently for
    > all
    > of those systems.
    > 
    > if they're all
    > logging in with the same role and just a different password, that's
    > not
    > going to happen.
    
    I'm not sure this is a great idea. Can you point to some precedent
    here?
    
    
    > Giving users the option of not having to specify a name and letting
    > the
    > system come up with one (similar to what we do for indexes and such)
    > could work out pretty decently, imv.  I'd have that be optional
    > though-
    > if the user wants to specify a name, then they should be allowed to
    > do
    > so.
    
    Can you describe how some basic use cases should work with example SQL?
    
    > 
    > > * the identifier of the current password always changing (perhaps
    > > fine
    > > if it'a a "created at" ID?)
    > 
    > I'm not following what the issue is you're getting at here.
    
    I just meant that when rotating passwords, you have to keep coming up
    with new names, so the "current" or "primary" one would not have a
    consistent name.
    
    Regards,
    	Jeff Davis
    
    
    
    
    
  32. Re: [PoC/RFC] Multiple passwords, interval expirations

    Stephen Frost <sfrost@snowman.net> — 2023-10-18T02:52:05Z

    Greetings,
    
    * Jeff Davis (pgsql@j-davis.com) wrote:
    > On Tue, 2023-10-17 at 16:20 -0400, Stephen Frost wrote:
    > > Agreed that it's a bad idea to design to support 2 and only 2.
    > 
    > I don't disagree, but it's difficult to come up with syntax that:
    > 
    >  (a) supports N passwords
    >  (b) makes the ordinary cases simple and documentable
    >  (c) helps users avoid mistakes (at least in the simple cases)
    >  (d) makes sense passwords with and without validity period
    >  (e) handles the challenging cases
    
    Undoubtably biased ... but I don't agree that this is so difficult.
    What points have been raised as a downside of the originally proposed
    approach, specifically?
    
    Reading back through the thread, from a user perspective, the primary
    one seems to be that passwords are expected to be named.  I'm surprised
    this is being brought up as such a serious concern.  Lots and lots and
    lots of things in the system require naming, after all, and the idea
    that this is somehow harder or more of an issue is quite odd to me.
    
    > One challenging case is that we cannot allow the mixing of password
    > protocols (e.g. MD5 & SCRAM), because the authentication exchange only
    > gets one chance at success. If someone ends up with 7 MD5 passwords,
    > and they'd like to migrate to SCRAM, then we can't allow them to
    > migrate one password at a time (because then the other passwords would
    > break). I'd like to see what the SQL for doing this should look like.
    
    I've got absolutely no interest in supporting md5- it's high time to rip
    that out and be happy that it's gone.  We nearly did it last year and
    I'm really hoping we accomplish that this year.
    
    I'm open to the idea that we may need to support some new SCRAM version
    or an alternative mechanism in the future, but it's long past time to
    spend any time worrying about md5.  As for how difficult it is to deal
    with supporting an alternative in the future- that's going to depend a
    great deal on what that alternative is and I don't know that we can
    really code to handle that as part of this effort in a sensible way, and
    trying to code for "anything" is going to likely make this much more
    complicated, and probably rife with security issues too.
    
    > >   If
    > > nothing else, there's the very simple case that the user needs to do
    > > another password rotation ... and they look and discover that the old
    > > password is still being used and that if they took it away, things
    > > would
    > > break, but they need time to run down which system is still using it
    > > while still needing to perform the migration for the other systems
    > > that
    > > are correctly being updated- boom, need 3 for that case.
    > 
    > That sounds like a reasonable use case. I don't know if we should make
    > it a requirement, but if we come up with something reasonable that
    > supports this case I'm fine with it. Ideally, it would still be easy to
    > see when you are making a mistake (e.g. forgetting to ever remove
    > passwords).
    
    We have monitoring for many, many parts of the system and this would be
    a good thing to monitor also- not just at a per-password level but also
    at an overall role/user level, as you have a similar issue there and we
    don't properly provide users with any way to check reasonably "hey, when
    was the last time this user logged in?".  No, trawling through ancient
    logs, if you even have them, isn't a proper solution to this problem.
    
    > >   There's other
    > > use-cases that could be interesting though- presumably we'd log which
    > > password is used to authenticate and then users could have a fleet of
    > > web servers which each have their own password but log into the same
    > > PG
    > > user and they could happily rotate the passwords independently for
    > > all
    > > of those systems.
    > > 
    > > if they're all
    > > logging in with the same role and just a different password, that's
    > > not
    > > going to happen.
    > 
    > I'm not sure this is a great idea. Can you point to some precedent
    > here?
    
    It's already the case that lots and lots and lots of systems out there
    log into PG using the same username/password.  With this, we're at least
    offering them the ability to vary the password and keep the user the
    same.  We've even seen this be asked for in other ways- the ability to
    use distinct Kerberos or LDAP identifies to log into the same user in
    the database, see pg_ident.conf and various suggestions for how to bring
    that to LDAP too.  Other systems also support the ability to have a
    group of users in LDAP, or such, be allowed to log into a specific
    database user.  One big reason for this is that then you know everyong
    logging into that account has exactly the same access to things- because
    that's the lowest level at which access can be granted.  Having a way to
    support this similar capability but for passwords is certainly useful.
    
    > > Giving users the option of not having to specify a name and letting
    > > the
    > > system come up with one (similar to what we do for indexes and such)
    > > could work out pretty decently, imv.  I'd have that be optional
    > > though-
    > > if the user wants to specify a name, then they should be allowed to
    > > do
    > > so.
    > 
    > Can you describe how some basic use cases should work with example SQL?
    
    As mentioned, we have this general idea already; a simplified CREATE
    INDEX syntax can be used as an example:
    
    CREATE INDEX [ [ IF NOT EXISTS ] name ] ON table_name ...
    
    and so we could have:
    
    CREATE PASS [ [ IF NOT EXISTS ] name ] FOR role ...
    
    Giving the user the option of providing a name, but just generating one
    if the user declines to include a name.  Naturally, users would have to
    have some way to look up the names but that doesn't seem difficult to
    provide such as through some \du command, along with appropriate views,
    just like we have for indexes.
    
    I do generally feel like the original patch was lacking when it came to
    syntax and password management functions, but I don't think the answer
    to that is to just throw away the whole concept of multiple passwords in
    favor of only supporting a very limited number of them.  I'd think we'd
    work towards improving on the syntax to support what we think users will
    need to make all of this work smoothly.
    
    > > > * the identifier of the current password always changing (perhaps
    > > > fine
    > > > if it'a a "created at" ID?)
    > > 
    > > I'm not following what the issue is you're getting at here.
    > 
    > I just meant that when rotating passwords, you have to keep coming up
    > with new names, so the "current" or "primary" one would not have a
    > consistent name.
    
    Do we need a current or primary?  How is that defined, exactly?  If we
    want it, we could surely create it and make it work, but we'd need to
    have a good understand of just what it is and why it's the 'current' or
    'primary' and I'm not sure that we've actually got a good definition for
    that and I'm not convinced yet that we should.
    
    Thanks,
    
    Stephen
    
  33. Re: [PoC/RFC] Multiple passwords, interval expirations

    Jeff Davis <pgsql@j-davis.com> — 2023-10-18T16:40:02Z

    On Tue, 2023-10-17 at 22:52 -0400, Stephen Frost wrote:
    
    > Reading back through the thread, from a user perspective, the primary
    > one seems to be that passwords are expected to be named.  I'm
    > surprised
    > this is being brought up as such a serious concern.  Lots and lots
    > and
    > lots of things in the system require naming, after all, and the idea
    > that this is somehow harder or more of an issue is quite odd to me.
    
    In the simplest intended use case, the names will be arbitrary and
    temporary. It's easy for me to imagine someone wondering "was I
    supposed to delete 'bear' or 'lion'?". For indexes and other objects,
    there's a lot more to go on, easily visible with \d.
    
    Now, obviously that is not the end of the world, and the user could
    prevent that problem a number of different ways. And we can do things
    like improve the monitoring of password use, and store the password
    creation time, to help users if they are confused. So I don't raise
    concerns about naming as an objection to the feature overall, but
    rather a concern that we aren't getting it quite right.
    
    Maybe a name should be entirely optional, more like a comment, and the
    passwords can be referenced by the salt? The salt needs to be unique
    for a given user anyway.
    
    (Aside: is the uniqueness of the salt enforced in the current patch?)
    
    Regards,
    	Jeff Davis
    
    
    
    
    
  34. Re: [PoC/RFC] Multiple passwords, interval expirations

    Stephen Frost <sfrost@snowman.net> — 2023-10-18T18:48:22Z

    Greetings,
    
    * Jeff Davis (pgsql@j-davis.com) wrote:
    > On Tue, 2023-10-17 at 22:52 -0400, Stephen Frost wrote:
    > 
    > > Reading back through the thread, from a user perspective, the primary
    > > one seems to be that passwords are expected to be named.  I'm
    > > surprised
    > > this is being brought up as such a serious concern.  Lots and lots
    > > and
    > > lots of things in the system require naming, after all, and the idea
    > > that this is somehow harder or more of an issue is quite odd to me.
    > 
    > In the simplest intended use case, the names will be arbitrary and
    > temporary. It's easy for me to imagine someone wondering "was I
    > supposed to delete 'bear' or 'lion'?". For indexes and other objects,
    > there's a lot more to go on, easily visible with \d.
    
    Sure, agreed.
    
    > Now, obviously that is not the end of the world, and the user could
    > prevent that problem a number of different ways. And we can do things
    > like improve the monitoring of password use, and store the password
    > creation time, to help users if they are confused. So I don't raise
    > concerns about naming as an objection to the feature overall, but
    > rather a concern that we aren't getting it quite right.
    
    Right, we need more observability, agreed, but that's not strictly
    necessary of this patch and could certainly be added independently.  Is
    there really a need to make this observability a requirement of this
    particular change?
    
    > Maybe a name should be entirely optional, more like a comment, and the
    > passwords can be referenced by the salt? The salt needs to be unique
    > for a given user anyway.
    
    I proposed an approach in the email you replied to explicitly suggesting
    a way we could make the name be optional, so, sure, I'm generally on
    board with that idea.  Note that it'd be optional for the user to
    provide and then we'd simply generate one for them and then that name is
    what would be used to refer to that password later.
    
    > (Aside: is the uniqueness of the salt enforced in the current patch?)
    
    Err, the salt has to be *identical* for each password of a given user,
    not unique, so I'm a bit confused here.
    
    Thanks,
    
    Stephen
    
  35. Re: [PoC/RFC] Multiple passwords, interval expirations

    Jeff Davis <pgsql@j-davis.com> — 2023-10-20T02:22:07Z

    On Wed, 2023-10-18 at 14:48 -0400, Stephen Frost wrote:
    > Right, we need more observability, agreed, but that's not strictly
    > necessary of this patch and could certainly be added independently. 
    > Is
    > there really a need to make this observability a requirement of this
    > particular change?
    
    I won't draw a line in the sand, but it feels like something should be
    there to help the user keep track of which password they might want to
    keep. At least a "created on" date or something.
    
    > > (Aside: is the uniqueness of the salt enforced in the current
    > > patch?)
    > 
    > Err, the salt has to be *identical* for each password of a given
    > user,
    > not unique, so I'm a bit confused here.
    
    Sorry, my mistake.
    
    If the client needs to use the same salt as existing passwords, can you
    still use PQencryptPasswordConn() on the client to avoid sending the
    plaintext password to the server?
    
    Regards,
    	Jeff Davis
    
    
    
    
    
  36. Re: [PoC/RFC] Multiple passwords, interval expirations

    Stephen Frost <sfrost@snowman.net> — 2023-10-20T12:35:04Z

    Greetings,
    
    * Jeff Davis (pgsql@j-davis.com) wrote:
    > On Wed, 2023-10-18 at 14:48 -0400, Stephen Frost wrote:
    > > Right, we need more observability, agreed, but that's not strictly
    > > necessary of this patch and could certainly be added independently. 
    > > Is
    > > there really a need to make this observability a requirement of this
    > > particular change?
    > 
    > I won't draw a line in the sand, but it feels like something should be
    > there to help the user keep track of which password they might want to
    > keep. At least a "created on" date or something.
    
    Sure, no objection to adding that and seems like it should be fairly
    easy ... but then again, I tend to feel that we should do that for all
    of the objects in the system and we've got some strong feelings against
    doing that from others.  Perhaps this case is different to them, in
    which case, great, but if it's not, it'd be unfortunate for this feature
    to get bogged down due to that.
    
    > > > (Aside: is the uniqueness of the salt enforced in the current
    > > > patch?)
    > > 
    > > Err, the salt has to be *identical* for each password of a given
    > > user,
    > > not unique, so I'm a bit confused here.
    > 
    > Sorry, my mistake.
    
    Sure, no worries.
    
    > If the client needs to use the same salt as existing passwords, can you
    > still use PQencryptPasswordConn() on the client to avoid sending the
    > plaintext password to the server?
    
    Short answer, yes ... but seems that wasn't actually done yet.  Requires
    a bit of additional work, since the client needs to get the existing
    salt (note that as part of the SCRAM typical exchange, the client is
    provided with the salt, so this isn't exposing anything new) to use to
    construct what is then sent to the server to store.  We'll also need to
    decide how to handle the case if the client tries to send a password
    that doesn't have the same salt as the existing ones (regardless of how
    many passwords we end up supporting).  Perhaps we require the user,
    through the grammar, to make clear if they want to add a password, and
    then error if they don't provide a matching salt, or if they want to
    remove existing passwords and replace with the new one.
    
    Thanks,
    
    Stephen
    
  37. Re: [PoC/RFC] Multiple passwords, interval expirations

    vignesh C <vignesh21@gmail.com> — 2024-01-27T01:48:59Z

    On Tue, 10 Oct 2023 at 16:37, Gurjeet Singh <gurjeet@singh.im> wrote:
    >
    > > On Mon, Oct 9, 2023 at 2:31 AM Gurjeet Singh <gurjeet@singh.im> wrote:
    > > >
    > > > Next steps:
    > > > - Break the patch into a series of smaller patches.
    > > > - Add TAP tests (test the ability to actually login with these passwords)
    > > > - Add/update documentation
    > > > - Add more regression tests
    >
    > Please see attached the v4 of the patchset that introduces the notion
    > of named passwords slots, namely 'first' and 'second' passwords, and
    > allows users to address each of these passwords separately for the
    > purposes of adding, dropping, or assigning expiration times.
    >
    > Apart from the changes described by each patch's commit title, one
    > significant change since v3 is that now (included in v4-0002...patch)
    > it is not allowed for a role to have a mix of a types of passwords.
    > When adding a password, the patch ensures that the password being
    > added uses the same hashing algorithm (md5 or scram-sha-256) as the
    > existing password, if any.  Having all passwords of the same type
    > helps the server pick the corresponding authentication method during
    > connection attempt.
    >
    > The v3 patch also had a few bugs that were exposed by cfbot's
    > automatic run. All those bugs have now been fixed, and the latest run
    > on the v4 branch [1] on my private Git repo shows a clean run [1].
    >
    > The list of patches, and their commit titles are as follows:
    >
    > > v4-0001-...patch Add new columns to pg_authid
    > > v4-0002-...patch Update password verification infrastructure to handle two passwords
    > > v4-0003-...patch Added SQL support for ALTER ROLE to manage two passwords
    > > v4-0004-...patch Updated pg_dumpall to support exporting a role's second password
    > > v4-0005-...patch Update system views pg_roles and pg_shadow
    > > v4-0006-...patch Updated pg_authid catalog documentation
    > > v4-0007-...patch Updated psql's describe-roles meta-command
    > > v4-0008-...patch Added documentation for ALTER ROLE command
    > > v4-0009-...patch Added TAP tests to prove that a role can use two passwords to login
    > > v4-0010-...patch pgindent run
    > > v4-0011-...patch Run pgperltidy on files changed by this patchset
    >
    > Running pgperltidy updated many perl files unrelated to this patch, so
    > in the last patch I chose to include only the one perl file that is
    > affected by this patchset.
    
    CFBot shows that the patch does not apply anymore as in [1]:
    === Applying patches on top of PostgreSQL commit ID
    4d969b2f85e1fd00e860366f101fd3e3160aab41 ===
    === applying patch
    ./v4-0002-Update-password-verification-infrastructure-to-ha.patch
    ...
    patching file src/backend/libpq/auth.c
    Hunk #4 FAILED at 828.
    Hunk #5 succeeded at 886 (offset -2 lines).
    Hunk #6 succeeded at 907 (offset -2 lines).
    1 out of 6 hunks FAILED -- saving rejects to file src/backend/libpq/auth.c.rej
    
    Please post an updated version for the same.
    
    [1] - http://cfbot.cputube.org/patch_46_4432.log
    
    Regards,
    Vignesh
    
    
    
    
  38. Re: [PoC/RFC] Multiple passwords, interval expirations

    vignesh C <vignesh21@gmail.com> — 2024-02-01T11:04:56Z

    On Sat, 27 Jan 2024 at 07:18, vignesh C <vignesh21@gmail.com> wrote:
    >
    > On Tue, 10 Oct 2023 at 16:37, Gurjeet Singh <gurjeet@singh.im> wrote:
    > >
    > > > On Mon, Oct 9, 2023 at 2:31 AM Gurjeet Singh <gurjeet@singh.im> wrote:
    > > > >
    > > > > Next steps:
    > > > > - Break the patch into a series of smaller patches.
    > > > > - Add TAP tests (test the ability to actually login with these passwords)
    > > > > - Add/update documentation
    > > > > - Add more regression tests
    > >
    > > Please see attached the v4 of the patchset that introduces the notion
    > > of named passwords slots, namely 'first' and 'second' passwords, and
    > > allows users to address each of these passwords separately for the
    > > purposes of adding, dropping, or assigning expiration times.
    > >
    > > Apart from the changes described by each patch's commit title, one
    > > significant change since v3 is that now (included in v4-0002...patch)
    > > it is not allowed for a role to have a mix of a types of passwords.
    > > When adding a password, the patch ensures that the password being
    > > added uses the same hashing algorithm (md5 or scram-sha-256) as the
    > > existing password, if any.  Having all passwords of the same type
    > > helps the server pick the corresponding authentication method during
    > > connection attempt.
    > >
    > > The v3 patch also had a few bugs that were exposed by cfbot's
    > > automatic run. All those bugs have now been fixed, and the latest run
    > > on the v4 branch [1] on my private Git repo shows a clean run [1].
    > >
    > > The list of patches, and their commit titles are as follows:
    > >
    > > > v4-0001-...patch Add new columns to pg_authid
    > > > v4-0002-...patch Update password verification infrastructure to handle two passwords
    > > > v4-0003-...patch Added SQL support for ALTER ROLE to manage two passwords
    > > > v4-0004-...patch Updated pg_dumpall to support exporting a role's second password
    > > > v4-0005-...patch Update system views pg_roles and pg_shadow
    > > > v4-0006-...patch Updated pg_authid catalog documentation
    > > > v4-0007-...patch Updated psql's describe-roles meta-command
    > > > v4-0008-...patch Added documentation for ALTER ROLE command
    > > > v4-0009-...patch Added TAP tests to prove that a role can use two passwords to login
    > > > v4-0010-...patch pgindent run
    > > > v4-0011-...patch Run pgperltidy on files changed by this patchset
    > >
    > > Running pgperltidy updated many perl files unrelated to this patch, so
    > > in the last patch I chose to include only the one perl file that is
    > > affected by this patchset.
    >
    > CFBot shows that the patch does not apply anymore as in [1]:
    > === Applying patches on top of PostgreSQL commit ID
    > 4d969b2f85e1fd00e860366f101fd3e3160aab41 ===
    > === applying patch
    > ./v4-0002-Update-password-verification-infrastructure-to-ha.patch
    > ...
    > patching file src/backend/libpq/auth.c
    > Hunk #4 FAILED at 828.
    > Hunk #5 succeeded at 886 (offset -2 lines).
    > Hunk #6 succeeded at 907 (offset -2 lines).
    > 1 out of 6 hunks FAILED -- saving rejects to file src/backend/libpq/auth.c.rej
    >
    > Please post an updated version for the same.
    
    The patch which you submitted has been awaiting your attention for
    quite some time now.  As such, we have moved it to "Returned with
    Feedback" and removed it from the reviewing queue. Depending on
    timing, this may be reversible.  Kindly address the feedback you have
    received, and resubmit the patch to the next CommitFest.
    
    Regards,
    Vignesh
    
    
    
    
  39. Re: [PoC/RFC] Multiple passwords, interval expirations

    Kirill Reshke <reshkekirill@gmail.com> — 2024-04-10T12:44:10Z

    Hi!
    
    I'm interested in this feature presence in the PostgreSQL core. Will
    try to provide valuable review/comments/suggestions and other help.
    
    On Tue, 10 Oct 2023 at 16:17, Gurjeet Singh <gurjeet@singh.im> wrote:
    >
    > > On Mon, Oct 9, 2023 at 2:31 AM Gurjeet Singh <gurjeet@singh.im> wrote:
    > > >
    > > > Next steps:
    > > > - Break the patch into a series of smaller patches.
    > > > - Add TAP tests (test the ability to actually login with these passwords)
    > > > - Add/update documentation
    > > > - Add more regression tests
    >
    > Please see attached the v4 of the patchset that introduces the notion
    > of named passwords slots, namely 'first' and 'second' passwords, and
    > allows users to address each of these passwords separately for the
    > purposes of adding, dropping, or assigning expiration times.
    >
    > Apart from the changes described by each patch's commit title, one
    > significant change since v3 is that now (included in v4-0002...patch)
    > it is not allowed for a role to have a mix of a types of passwords.
    > When adding a password, the patch ensures that the password being
    > added uses the same hashing algorithm (md5 or scram-sha-256) as the
    > existing password, if any.  Having all passwords of the same type
    > helps the server pick the corresponding authentication method during
    > connection attempt.
    >
    > The v3 patch also had a few bugs that were exposed by cfbot's
    > automatic run. All those bugs have now been fixed, and the latest run
    > on the v4 branch [1] on my private Git repo shows a clean run [1].
    >
    > The list of patches, and their commit titles are as follows:
    >
    > > v4-0001-...patch Add new columns to pg_authid
    > > v4-0002-...patch Update password verification infrastructure to handle two passwords
    > > v4-0003-...patch Added SQL support for ALTER ROLE to manage two passwords
    > > v4-0004-...patch Updated pg_dumpall to support exporting a role's second password
    > > v4-0005-...patch Update system views pg_roles and pg_shadow
    > > v4-0006-...patch Updated pg_authid catalog documentation
    > > v4-0007-...patch Updated psql's describe-roles meta-command
    > > v4-0008-...patch Added documentation for ALTER ROLE command
    > > v4-0009-...patch Added TAP tests to prove that a role can use two passwords to login
    > > v4-0010-...patch pgindent run
    > > v4-0011-...patch Run pgperltidy on files changed by this patchset
    >
    > Running pgperltidy updated many perl files unrelated to this patch, so
    > in the last patch I chose to include only the one perl file that is
    > affected by this patchset.
    >
    > [1]: password_rollover_v4 (910f81be54)
    > https://github.com/gurjeet/postgres/commits/password_rollover_v4
    >
    > [2]: https://cirrus-ci.com/build/4675613999497216
    >
    > Best regards,
    > Gurjeet
    > http://Gurje.et
    
    
    Latest attachment does not apply to HEAD anymore.  I have rebased
    them. While rebasing, a couple of minor changes were done:
    
    1) Little correction in the `plain_crypt_verify` comment. IMO this
    sounds a little better and comprehensible, is it?
    
    > - * 'shadow_pass' is the user's correct password hash, as stored in
    > - * pg_authid's rolpassword or rolsecondpassword.
    > + * 'shadow_pass' is one of the user's correct password hashes, as stored in
    > + * pg_authid's.
    
    2) in v4-0004:
    
    >        /* note: rolconfig is dumped later */
    > -       if (server_version >= 90600)
    > +       if (server_version >= 170000)
    >                printfPQExpBuffer(buf,
    >                                                  "SELECT oid, rolname, rolsuper, rolinherit, "
    >                                                  "rolcreaterole, rolcreatedb, "
    > -                                                 "rolcanlogin, rolconnlimit, rolpassword, "
    > -                                                 "rolvaliduntil, rolreplication, rolbypassrls, "
    > +                                                 "rolcanlogin, rolconnlimit, "
    > +                                                 "rolpassword, rolvaliduntil, "
    > +                                                 "rolsecondpassword, rolsecondvaliduntil, "
    > +                                                 "rolreplication, rolbypassrls, "
    > +                                                 "pg_catalog.shobj_description(oid, '%s') as rolcomment, "
    > +                                                 "rolname = current_user AS is_current_user "
    > +                                                 "FROM %s "
    > +                                                 "WHERE rolname !~ '^pg_' "
    > +                                                 "ORDER BY 2", role_catalog, role_catalog);
    > +       else if (server_version >= 90600)
    > +               printfPQExpBuffer(buf,
    > +                                                 "SELECT oid, rolname, rolsuper, rolinherit, "
    > +                                                 "rolcreaterole, rolcreatedb, "
    > +                                                 "rolcanlogin, rolconnlimit, "
    > +                                                 "rolpassword, rolvaliduntil, "
    > +                                                 "rolsecondpassword, rolsecodnvaliduntil, "
    > +                                                 "null as rolsecondpassword, null as rolsecondvaliduntil, "
    > +                                                 "rolreplication, rolbypassrls, "
    
    Is it a bug in server_version < 17000 && server_version >= 90600 case?
    we are trying to get   "rolsecondpassword, rolsecodnvaliduntil, " in
    this case? I have removed this, let me know if there is my
    misunderstanding.
    Also, if stmt changed to ` if (server_version >= 180000)` since pg17
    feature freeze.
    
    v4-0005 - v4-000 Applied cleanly, didn't touch them. But, I haven't
    reviewed them yet either.
    
    v4-0010-pgindent-run.patch - is it actually needed?
    
    Overall comments:
    
    1) AFAIU we are forcing all passwords to have/interact with the same
    salt. We really have no choice here, because in the case of SCRAM auth
    salt is used client-side to authenticate the server.I dont feel this
    is the best approach to restrict auth. process this much, though I
    didn't come up with strong objections to it. Anyway, what if we give
    the server a hint, which password to use in the startup message (in
    case users have more than one password)? This way we still can use
    different salts.
    
    2) I'm also not a big fan of max-2-password restriction. There are
    objections in the thread that having multiple passwords and named
    passwords leads to problems on the server-side, but I think that at
    least named passwords are a useful feature for those who use external
    Vault systems for password management. In this case, you can set the
    name of your password to the version of Vault secret, which is a very
    natural thing to do (and, thus, support it).
    
    3) Should we unite 0001 & 0004 patches in one? Or maybe 0003 & 0004?
    It is not a good idea to commit one of these patches without
    another.... (Since we can reach a database state that cannot be
    `pg_dump`-ed)
    
    
    So, that's it.