RFC 9266: Channel Bindings for TLS 1.3 support

Started by * Neustradamus *about 2 months ago32 messages
#1* Neustradamus *
neustradamus@hotmail.com

Dear PostgreSQL team, dear all,

In 2022, I have contacted PostgreSQL team about Channel Binding:
- https://www.postgresql.org/search/?m=1&q=tls-exporter&l=&d=-1&s=i

We are in 2025, I relaunch the subject because several developers always say me: "it is not supported by PostgreSQL".

Can you add the support of RFC 9266: Channel Bindings for TLS 1.3?
- https://datatracker.ietf.org/doc/html/rfc9266

Channel Bindings for TLS: https://datatracker.ietf.org/doc/html/rfc5929

- XEP-0388: Extensible SASL Profile: https://xmpp.org/extensions/xep-0388.html
- XEP-0440: SASL Channel-Binding Type Capability: https://xmpp.org/extensions/xep-0440.html
- XEP-0474: SASL SCRAM Downgrade Protection: https://xmpp.org/extensions/xep-0474.html
- XEP-0480: SASL Upgrade Tasks: https://xmpp.org/extensions/xep-0480.html

Little details, to know easily:
- tls-unique for TLS =< 1.2 (RFC5929)
- tls-server-end-point =< 1.2 + 1.3 (RFC5929)
- tls-exporter for TLS = 1.3 (RFC9266)

After the jabber.ru MITM, it is time to add it:
- https://notes.valdikss.org.ru/jabber.ru-mitm/
- https://snikket.org/blog/on-the-jabber-ru-mitm/
- https://www.devever.net/~hl/xmpp-incident
- https://blog.jmp.chat/b/certwatch/certwatch

Linked to:
- Channel Binding: https://github.com/scram-sasl/info/issues/1

Thanks in advance.

Regards,

Neustradamus

#2Heikki Linnakangas
hlinnaka@iki.fi
In reply to: * Neustradamus * (#1)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On 20/11/2025 22:58, * Neustradamus * wrote:

Dear PostgreSQL team, dear all,

In 2022, I have contacted PostgreSQL team about Channel Binding:
- https://www.postgresql.org/search/?m=1&amp;q=tls-exporter&amp;l=&amp;d=-1&amp;s=i

We are in 2025, I relaunch the subject because several developers always say me: "it is not supported by PostgreSQL".

Can you add the support of RFC 9266: Channel Bindings for TLS 1.3?
- https://datatracker.ietf.org/doc/html/rfc9266

I think that would be great. Patches are welcome!

The tricky part is probably going to be to make the protocol changes in
a way that is both backwards-compatible and as secure as possible. But
I'm sure it can be done.

Channel Bindings for TLS: https://datatracker.ietf.org/doc/html/rfc5929

- XEP-0388: Extensible SASL Profile: https://xmpp.org/extensions/xep-0388.html
- XEP-0440: SASL Channel-Binding Type Capability: https://xmpp.org/extensions/xep-0440.html
- XEP-0474: SASL SCRAM Downgrade Protection: https://xmpp.org/extensions/xep-0474.html
- XEP-0480: SASL Upgrade Tasks: https://xmpp.org/extensions/xep-0480.html

Little details, to know easily:
- tls-unique for TLS =< 1.2 (RFC5929)
- tls-server-end-point =< 1.2 + 1.3 (RFC5929)
- tls-exporter for TLS = 1.3 (RFC9266)

After the jabber.ru MITM, it is time to add it:
- https://notes.valdikss.org.ru/jabber.ru-mitm/
- https://snikket.org/blog/on-the-jabber-ru-mitm/
- https://www.devever.net/~hl/xmpp-incident
- https://blog.jmp.chat/b/certwatch/certwatch

PostgreSQL does support channel binding, with tls-server-end-point. I
believe that sufficient to prevent an attack like that. (Assuming that
it's configured correctly, but that's an issue of insecure defaults
rather than a missing feature).

What are the benefits of tls-exporter over tls-server-end-point? I agree
it would be good to support tls-exporter, since RFC9266 specifies it as
mandatory for channel binding over TLS 1.3. But aside from the RFC, is
there some practical difference?

- Heikki

#3Jacob Champion
jacob.champion@enterprisedb.com
In reply to: * Neustradamus * (#1)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Thu, Nov 20, 2025 at 12:59 PM * Neustradamus *
<neustradamus@hotmail.com> wrote:

In 2022, I have contacted PostgreSQL team about Channel Binding:
- https://www.postgresql.org/search/?m=1&amp;q=tls-exporter&amp;l=&amp;d=-1&amp;s=i

There was some initial work there [1]/messages/by-id/YwxWWQR6uwWHBCbQ@paquier.xyz, but we'd still need to figure
out channel binding negotiation, which seems like something we should
not be on the bleeding edge of.

I still wish we'd made endpoint binding opt-in, but that's water under
the bridge. The binding "infrastructure", such as it is, isn't really
in a healthy place right now (as you've seen [2]https://mailarchive.ietf.org/arch/msg/kitten/zpesKSHsiuy1RvhPlbSUGajLbKQ/), and I think we need
SASL to give us additional agility before we can really make progress.

We are in 2025, I relaunch the subject because several developers always say me: "it is not supported by PostgreSQL".

...who says that?

- XEP-0474: SASL SCRAM Downgrade Protection: https://xmpp.org/extensions/xep-0474.html

That says
WARNING: This Standards-Track document is Experimental.
Publication as an XMPP Extension Protocol does not imply approval of
this proposal by the XMPP Standards Foundation.
and
In the long term the author strives to publish this as an RFC
rather than a XEP to also make this protection available to other
protocols, after gaining implementation experience.
and
If [an RFC is published for this] implementations SHOULD NOT
implement this XEP and SHOULD implement the superseding RFC instead.

So we should probably not implement production features based on it.

Linked to:
- Channel Binding: https://github.com/scram-sasl/info/issues/1

(Looks like you're on thin ice with several of the projects listed
there. Please treat other OSS communities with respect, and don't spam
their repositories.)

Thanks,
--Jacob

[1]: /messages/by-id/YwxWWQR6uwWHBCbQ@paquier.xyz
[2]: https://mailarchive.ietf.org/arch/msg/kitten/zpesKSHsiuy1RvhPlbSUGajLbKQ/

#4Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Heikki Linnakangas (#2)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Thu, Nov 20, 2025 at 1:52 PM Heikki Linnakangas <hlinnaka@iki.fi> wrote:

PostgreSQL does support channel binding, with tls-server-end-point. I
believe that sufficient to prevent an attack like that.

No, IIRC unique bindings (-unique and -exporter) prevent MITM even if
the attacker has the server's private key, as long as they do not also
possess the SCRAM verifiers. tls-server-end-point does not prevent
against that (so you can terminate TLS on a different node from the
verifiers).

--Jacob

#5* Neustradamus *
neustradamus@hotmail.com
In reply to: Heikki Linnakangas (#2)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

Dear Heikki,

Thanks for your answer.

Several people would like to deprecate "tls-server-end-point" (RFC 5929) like Simon Josefsson (author of several RFCs) because RFC 9266 exists since July 2022:
- https://mailarchive.ietf.org/arch/msg/kitten/zpesKSHsiuy1RvhPlbSUGajLbKQ/
- https://datatracker.ietf.org/person/Simon%20Josefsson

For example, he is the GNU SASL maintainer and he does not want to add tls-server-end-point support:
- https://gitlab.com/gsasl/gsasl/-/issues/13

Other talks about tls-server-end-point:
- https://mailarchive.ietf.org/arch/browse/kitten/?q=tls-server-end-point&amp;gbt=1&amp;index=
- https://mail.jabber.org/hyperkitty/search?count=200&amp;q=tls-server-end-point&amp;page=1&amp;mlist=standards%40xmpp.org&amp;sort=date-asc
- https://mailarchive.ietf.org/arch/browse/tls/?q=tls-server-end-point&amp;gbt=1&amp;index=

So it is really important to support "tls-exporter".

Regards,

Neustradamus

________________________________________
From: Heikki Linnakangas <hlinnaka@iki.fi>
Sent: Thursday, November 20, 2025 22:52
To: * Neustradamus *; PostgreSQL Hackers
Subject: Re: RFC 9266: Channel Bindings for TLS 1.3 support

On 20/11/2025 22:58, * Neustradamus * wrote:

Dear PostgreSQL team, dear all,

In 2022, I have contacted PostgreSQL team about Channel Binding:
- https://www.postgresql.org/search/?m=1&amp;q=tls-exporter&amp;l=&amp;d=-1&amp;s=i

We are in 2025, I relaunch the subject because several developers always say me: "it is not supported by PostgreSQL".

Can you add the support of RFC 9266: Channel Bindings for TLS 1.3?
- https://datatracker.ietf.org/doc/html/rfc9266

I think that would be great. Patches are welcome!

The tricky part is probably going to be to make the protocol changes in
a way that is both backwards-compatible and as secure as possible. But
I'm sure it can be done.

Channel Bindings for TLS: https://datatracker.ietf.org/doc/html/rfc5929

- XEP-0388: Extensible SASL Profile: https://xmpp.org/extensions/xep-0388.html
- XEP-0440: SASL Channel-Binding Type Capability: https://xmpp.org/extensions/xep-0440.html
- XEP-0474: SASL SCRAM Downgrade Protection: https://xmpp.org/extensions/xep-0474.html
- XEP-0480: SASL Upgrade Tasks: https://xmpp.org/extensions/xep-0480.html

Little details, to know easily:
- tls-unique for TLS =< 1.2 (RFC5929)
- tls-server-end-point =< 1.2 + 1.3 (RFC5929)
- tls-exporter for TLS = 1.3 (RFC9266)

After the jabber.ru MITM, it is time to add it:
- https://notes.valdikss.org.ru/jabber.ru-mitm/
- https://snikket.org/blog/on-the-jabber-ru-mitm/
- https://www.devever.net/~hl/xmpp-incident
- https://blog.jmp.chat/b/certwatch/certwatch

PostgreSQL does support channel binding, with tls-server-end-point. I
believe that sufficient to prevent an attack like that. (Assuming that
it's configured correctly, but that's an issue of insecure defaults
rather than a missing feature).

What are the benefits of tls-exporter over tls-server-end-point? I agree
it would be good to support tls-exporter, since RFC9266 specifies it as
mandatory for channel binding over TLS 1.3. But aside from the RFC, is
there some practical difference?

- Heikki

#6Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Jacob Champion (#4)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On 20/11/2025 23:59, Jacob Champion wrote:

On Thu, Nov 20, 2025 at 1:52 PM Heikki Linnakangas <hlinnaka@iki.fi> wrote:

PostgreSQL does support channel binding, with tls-server-end-point. I
believe that sufficient to prevent an attack like that.

No, IIRC unique bindings (-unique and -exporter) prevent MITM even if
the attacker has the server's private key, as long as they do not also
possess the SCRAM verifiers. tls-server-end-point does not prevent
against that (so you can terminate TLS on a different node from the
verifiers).

If I understood the incident correctly, the attacker managed to somehow
obtain a valid TLS certificate for the victim domain. They used that to
perform a MITM attack. They did not have the server's private key. (Or
if they did, they did not use that for the attack).

That's an advantage in general though, even if it wouldn't have made a
difference in this instance. So fair point.

- Heikki

#7* Neustradamus *
neustradamus@hotmail.com
In reply to: Jacob Champion (#3)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

Dear Jacob Champion,

Thanks for your answer.

Links of XEPs are here to confirm that "tls-exporter" is needed and already used.

XEPs are already supported by a lot of projects/softwares/companies in production, for example on GitHub, we can see:
- https://github.com/search?q=XEP-0480+-repo%3Axsf%2Fxeps+-repo%3Axsf%2Fxep-attic+-repo%3Axsf%2Fxmpp.org&amp;type=code
- https://github.com/search?q=XEP-0388+-repo%3Axsf%2Fxeps+-repo%3Axsf%2Fxep-attic+-repo%3Axsf%2Fxmpp.org&amp;type=code
- https://github.com/search?q=XEP-0440+-repo%3Axsf%2Fxeps+-repo%3Axsf%2Fxep-attic+-repo%3Axsf%2Fxmpp.org&amp;type=code
- https://github.com/search?q=XEP-0474+-repo%3Axsf%2Fxeps+-repo%3Axsf%2Fxep-attic+-repo%3Axsf%2Fxmpp.org&amp;type=code

XEP-0001 specify "Experimental" states:
- https://xmpp.org/extensions/xep-0001.html#states-Experimental

At the same time, about these XEPs, it is the base of the "draft-melnikov-sasl2" done by Alexey Melnikov (author of several RFCs):
- https://datatracker.ietf.org/doc/html/draft-melnikov-sasl2
- https://datatracker.ietf.org/person/Alexey%20Melnikov

I have informed several projects about SCRAM-SHA-*, SCRAM-SHA-*-PLUS (SCRAM-SHA-* with Channel Binding), and Channel Binding since a very long time.
The support of different SCRAM versions and/or different Channel Binding versions have been added in a lot of projects/softwares/libraries with success.
Of course, it is not yet perfect everywhere.
The security is important.

Other GitHub searches in code (Good commented source codes are good):
- tls-server-end-point: https://github.com/search?q=tls-server-end-point&amp;type=code
- tls-exporter: https://github.com/search?q=tls-exporter&amp;type=code
- rfc5929: https://github.com/search?q=rfc5929&amp;type=code
- rfc9266: https://github.com/search?q=rfc9266&amp;type=code
- rfc 5929: https://github.com/search?q=%22rfc+5929%22&amp;type=code
- rfc 9266: https://github.com/search?q=%22rfc+9266%22&amp;type=code

For more informations to all, I can add Wikipedia links about Salted Challenge Response Authentication Mechanism (SCRAM) and Channel Binding:
- https://en.wikipedia.org/wiki/Salted_Challenge_Response_Authentication_Mechanism
- https://en.wikipedia.org/wiki/Salted_Challenge_Response_Authentication_Mechanism#Channel_binding

Note: Channel Binding is not only linked to SCRAM.

Regards,

Neustradamus

________________________________________
From: Jacob Champion <jacob.champion@enterprisedb.com>
Sent: Thursday, November 20, 2025 22:52
To: * Neustradamus *
Cc: PostgreSQL Hackers
Subject: Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Thu, Nov 20, 2025 at 12:59 PM * Neustradamus *
<neustradamus@hotmail.com> wrote:

In 2022, I have contacted PostgreSQL team about Channel Binding:
- https://www.postgresql.org/search/?m=1&amp;q=tls-exporter&amp;l=&amp;d=-1&amp;s=i

There was some initial work there [1]/messages/by-id/YwxWWQR6uwWHBCbQ@paquier.xyz, but we'd still need to figure
out channel binding negotiation, which seems like something we should
not be on the bleeding edge of.

I still wish we'd made endpoint binding opt-in, but that's water under
the bridge. The binding "infrastructure", such as it is, isn't really
in a healthy place right now (as you've seen [2]https://mailarchive.ietf.org/arch/msg/kitten/zpesKSHsiuy1RvhPlbSUGajLbKQ/), and I think we need
SASL to give us additional agility before we can really make progress.

We are in 2025, I relaunch the subject because several developers always say me: "it is not supported by PostgreSQL".

...who says that?

- XEP-0474: SASL SCRAM Downgrade Protection: https://xmpp.org/extensions/xep-0474.html

That says
WARNING: This Standards-Track document is Experimental.
Publication as an XMPP Extension Protocol does not imply approval of
this proposal by the XMPP Standards Foundation.
and
In the long term the author strives to publish this as an RFC
rather than a XEP to also make this protection available to other
protocols, after gaining implementation experience.
and
If [an RFC is published for this] implementations SHOULD NOT
implement this XEP and SHOULD implement the superseding RFC instead.

So we should probably not implement production features based on it.

Linked to:
- Channel Binding: https://github.com/scram-sasl/info/issues/1

(Looks like you're on thin ice with several of the projects listed
there. Please treat other OSS communities with respect, and don't spam
their repositories.)

Thanks,
--Jacob

[1]: /messages/by-id/YwxWWQR6uwWHBCbQ@paquier.xyz
[2]: https://mailarchive.ietf.org/arch/msg/kitten/zpesKSHsiuy1RvhPlbSUGajLbKQ/

#8Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Heikki Linnakangas (#6)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 12:46 AM Heikki Linnakangas <hlinnaka@iki.fi> wrote:

If I understood the incident correctly, the attacker managed to somehow
obtain a valid TLS certificate for the victim domain. They used that to
perform a MITM attack. They did not have the server's private key. (Or
if they did, they did not use that for the attack).

Oh! Thank you for pointing that out. Yeah, having the private key for
*a* host certificate shouldn't help you if it doesn't have the same
public fingerprint as the one in use at the peer. (I'm not sure I
really internalized that distinction before.)

--Jacob

#9Jacob Champion
jacob.champion@enterprisedb.com
In reply to: * Neustradamus * (#7)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 12:49 AM * Neustradamus *
<neustradamus@hotmail.com> wrote:

At the same time, about these XEPs, it is the base of the "draft-melnikov-sasl2" done by Alexey Melnikov (author of several RFCs):
- https://datatracker.ietf.org/doc/html/draft-melnikov-sasl2

Right, but even that draft says

All of the features below are optional (in order to remain backward
compatible with RFC 4422). However if any is implemented, all of
them MUST be implemented in a protocol. This makes client
implementations easier.

So even if we were to charge ahead and assume that the XEP
implementation is exactly what's going to be standardized in a future
version of SASL, we're still introducing interoperability pain if we
don't do other currently-experimental things too.

In the past, we've said that we're going to wait for published RFCs,
and I think that's served us well. We just need to keep an eye on what
the Kitten WG is up to.

That doesn't stop anyone from maintaining a patchset that tracks the
state of the drafts, though. It's only a barrier to getting it
committed and released.

Thanks,
--Jacob

#10Daniel Gustafsson
daniel@yesql.se
In reply to: Jacob Champion (#9)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On 21 Nov 2025, at 17:38, Jacob Champion <jacob.champion@enterprisedb.com> wrote:

In the past, we've said that we're going to wait for published RFCs,
and I think that's served us well.

I am a strong supporter of this strategy.

--
Daniel Gustafsson

#11Nico Williams
nico@cryptonector.com
In reply to: Heikki Linnakangas (#2)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Thu, Nov 20, 2025 at 11:52:07PM +0200, Heikki Linnakangas wrote:

After the jabber.ru MITM, it is time to add it:

PostgreSQL does support channel binding, with tls-server-end-point. I
believe that sufficient to prevent an attack like that. (Assuming that it's
configured correctly, but that's an issue of insecure defaults rather than a
missing feature).

Yes, tls-server-end-point is sufficient.

What are the benefits of tls-exporter over tls-server-end-point? I agree it
would be good to support tls-exporter, since RFC9266 specifies it as
mandatory for channel binding over TLS 1.3. But aside from the RFC, is there
some practical difference?

tls-server-end-point suffers from a design problem: it assumes that
signature algorithms have an asssociated digest function, but this turns
out not to be true, and so for some signature algorithms the tls-server-
end-point CB data are undefined :( (you can blame me and my co-authors
for this). Using the exporter-based CB you will not have this problem.

The main benefit of "end-point"-style CB data is that it's easier to
deal with server-side ("reverse") proxies. That's primarily a benefit
for HTTP applications, and almost certainly not relevant to PG (unless
there _are_ reverse proxies for PG -- are there?).

(It _was_ also easier to implement end-point CB when the TLS library
doesn't support the exporter -- that was a problem 15 years ago, but not
now.)

Nico
--

#12Nico Williams
nico@cryptonector.com
In reply to: * Neustradamus * (#5)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 08:30:42AM +0000, * Neustradamus * wrote:

Dear Heikki,

Thanks for your answer.

Several people would like to deprecate "tls-server-end-point" (RFC 5929) like Simon Josefsson (author of several RFCs) because RFC 9266 exists since July 2022:

We must either fix or _replace_ tls-server-end-point (TSEP), but we
cannot not have end-point-style CB. I followed up to Simon with reasons
for why. Those followups will also answer Heikki's questions about
pros/cons.

That said, for _PG_ I think the exporter CB are almost certainly better.

Nico
--

#13Nico Williams
nico@cryptonector.com
In reply to: * Neustradamus * (#1)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Thu, Nov 20, 2025 at 08:58:54PM +0000, * Neustradamus * wrote:

- XEP-0388: Extensible SASL Profile: https://xmpp.org/extensions/xep-0388.html
- XEP-0440: SASL Channel-Binding Type Capability: https://xmpp.org/extensions/xep-0440.html
- XEP-0474: SASL SCRAM Downgrade Protection: https://xmpp.org/extensions/xep-0474.html
- XEP-0480: SASL Upgrade Tasks: https://xmpp.org/extensions/xep-0480.html

Why are XEPs relevant to PG?

#14Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#4)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Thu, Nov 20, 2025 at 01:59:22PM -0800, Jacob Champion wrote:

On Thu, Nov 20, 2025 at 1:52 PM Heikki Linnakangas <hlinnaka@iki.fi> wrote:

PostgreSQL does support channel binding, with tls-server-end-point. I
believe that sufficient to prevent an attack like that.

No, IIRC unique bindings (-unique and -exporter) prevent MITM even if
the attacker has the server's private key, as long as they do not also
possess the SCRAM verifiers. tls-server-end-point does not prevent
against that (so you can terminate TLS on a different node from the
verifiers).

If the attacker has the server's private keys then presumably also have
the credentials needed to also terminate the SASL/GSS-API mechanism's
server/acceptor side, so channel binding will not protect you.

The original intent for channel binding was so we could have channels
that authenticate end-points either very weakly (IPsec) or not at all
(TLS w/ anonymous ciphersuites, IPsec w/ BTNS). But channel binding
also serves to detect unwanted proxies -- not wanted by the app, but
maybe wanted by the user. Channel binding has also inspired various
token binding schemes to reduce the risk of bearer token compromise.

Nico
--

#15Nico Williams
nico@cryptonector.com
In reply to: Daniel Gustafsson (#10)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 06:24:07PM +0100, Daniel Gustafsson wrote:

On 21 Nov 2025, at 17:38, Jacob Champion <jacob.champion@enterprisedb.com> wrote:

In the past, we've said that we're going to wait for published RFCs,
and I think that's served us well.

I am a strong supporter of this strategy.

+1

#16Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Nico Williams (#14)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 9:28 AM Nico Williams <nico@cryptonector.com> wrote:

The main benefit of "end-point"-style CB data is that it's easier to
deal with server-side ("reverse") proxies. That's primarily a benefit
for HTTP applications, and almost certainly not relevant to PG (unless
there _are_ reverse proxies for PG -- are there?).

There is some newer/in-progress work that's beginning to converge on
that, yes (direct-mode SSL+ALPN, server-side SNI, others?).

On Fri, Nov 21, 2025 at 9:38 AM Nico Williams <nico@cryptonector.com> wrote:

If the attacker has the server's private keys then presumably also have
the credentials needed to also terminate the SASL/GSS-API mechanism's
server/acceptor side, so channel binding will not protect you.

Why does that follow? I would think that the avenues for leaking a key
in today's containerized world are much different from the avenues for
leaking database credentials. Or do I misunderstand what you mean...?
I want to make sure I haven't misled people on our SCRAM guarantees...

(But I agree with you that most people probably want unique bindings
for the default use case, not end-point bindings.)

Thanks,
--Jacob

#17Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#16)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 10:21:41AM -0800, Jacob Champion wrote:

On Fri, Nov 21, 2025 at 9:38 AM Nico Williams <nico@cryptonector.com> wrote:

If the attacker has the server's private keys then presumably also have
the credentials needed to also terminate the SASL/GSS-API mechanism's
server/acceptor side, so channel binding will not protect you.

Why does that follow? I would think that the avenues for leaking a key
in today's containerized world are much different from the avenues for
leaking database credentials. Or do I misunderstand what you mean...?
I want to make sure I haven't misled people on our SCRAM guarantees...

Well, you're right that if we're talking about a Heartbleed type leak
then what I said does not follow. However loss of the TLS server
credential's private keys is still close enough to catastrophic.

That reminds me of another motivation for channel binding: protection
against wayward CAs. In the WebPKI this is reasonably well accomplished
by certificate transparency, but it's still nice to be able to use CB to
protect against that. In corporate networks (where PG is mostly
deployed, no?) this is not that interesting a consideration.

(But I agree with you that most people probably want unique bindings
for the default use case, not end-point bindings.)

The situation has changed. In the mid- to late-00s unique CB support
was harder to come by. But EP CB is still useful for HTTP applications
for reasons having to do with reverse proxies.

Nico
--

#18Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Nico Williams (#17)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 11:17 AM Nico Williams <nico@cryptonector.com> wrote:

Well, you're right that if we're talking about a Heartbleed type leak
then what I said does not follow. However loss of the TLS server
credential's private keys is still close enough to catastrophic.

Sure, but it's nice that SCRAM (the only thing we use bindings for at
the moment) makes it slightly less catastrophic. I just wanted to make
sure that the property of "attacker must have the private key and the
SCRAM verifiers to fully masquerade" had not collapsed into "private
key is sufficient" for some reason.

That reminds me of another motivation for channel binding: protection
against wayward CAs. In the WebPKI this is reasonably well accomplished
by certificate transparency, but it's still nice to be able to use CB to
protect against that. In corporate networks (where PG is mostly
deployed, no?) this is not that interesting a consideration.

"Mostly" is probably still accurate? But WebPKI is more important for
us than it used to be, I think. (And with the recent demise of OCSP,
additional server authentication factors may help fill the gap for
some people, maybe?)

Thanks!
--Jacob

#19Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#18)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 11:42:41AM -0800, Jacob Champion wrote:

On Fri, Nov 21, 2025 at 11:17 AM Nico Williams <nico@cryptonector.com> wrote:

Well, you're right that if we're talking about a Heartbleed type leak
then what I said does not follow. However loss of the TLS server
credential's private keys is still close enough to catastrophic.

Sure, but it's nice that SCRAM (the only thing we use bindings for at
the moment) makes it slightly less catastrophic. I just wanted to make
sure that the property of "attacker must have the private key and the
SCRAM verifiers to fully masquerade" had not collapsed into "private
key is sufficient" for some reason.

That's a fair take.

(I'm very down on SCRAM. I'd much rather have an asymmetric zero-
knowledge PAKE.)

That reminds me of another motivation for channel binding: protection
against wayward CAs. In the WebPKI this is reasonably well accomplished
by certificate transparency, but it's still nice to be able to use CB to
protect against that. In corporate networks (where PG is mostly
deployed, no?) this is not that interesting a consideration.

"Mostly" is probably still accurate? But WebPKI is more important for

Correct. CT is not a silver bullet.

us than it used to be, I think. (And with the recent demise of OCSP,
additional server authentication factors may help fill the gap for
some people, maybe?)

Fair enough, as more public cloud PG offerings come along, WebPKI will
matter more to PG.

I wonder if DANE (DNS-based Authentication of Named Entities [RFC 6698])
might be a good idea for PG. IMO DANE is a great idea in general, but
browser communities do not agree yet (for reasons, often to do with
performance, which I think by and large do not apply to PG).

Nico
--

#20Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Nico Williams (#19)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 11:57 AM Nico Williams <nico@cryptonector.com> wrote:

(I'm very down on SCRAM. I'd much rather have an asymmetric zero-
knowledge PAKE.)

Hey, get an OPAQUE-PLUS over the line and I bet someone here will take
interest :D

(It's hard for me to be more down on SCRAM than I am on plaintext
LDAP, though. SCRAM's pretty good.)

I wonder if DANE (DNS-based Authentication of Named Entities [RFC 6698])
might be a good idea for PG. IMO DANE is a great idea in general, but
browser communities do not agree yet (for reasons, often to do with
performance, which I think by and large do not apply to PG).

Possibly. I did briefly look at RPK a few months back, but that was in
the context of a pinned key (i.e. "SSH into Postgres") rather than
with DANE. I feel like I've seen people talking about DANE a lot more
recently? Maybe there'll be momentum for that at some point.

--Jacob

#21Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#20)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Fri, Nov 21, 2025 at 02:57:26PM -0800, Jacob Champion wrote:

On Fri, Nov 21, 2025 at 11:57 AM Nico Williams <nico@cryptonector.com> wrote:

(I'm very down on SCRAM. I'd much rather have an asymmetric zero-
knowledge PAKE.)

Hey, get an OPAQUE-PLUS over the line and I bet someone here will take
interest :D

For apps like PG I'm much more interested in real OAuth support. But
that's because I use PG in a corporate environment where we use
Kerberos, PKIX, and OAuth for authentication.

In particular I want the _client_ to be configurable to be smart enough
as to how to fetch the darned OAuth rock the server wants. I'm much
more interested in OAuth for authentication than I am in OAuth for
authorization -- GRANTs and RLS (and/or VIEWs that JOIN authz tables)
are plenty good enough for authz in PG.

(It's hard for me to be more down on SCRAM than I am on plaintext
LDAP, though. SCRAM's pretty good.)

+1

I wonder if DANE (DNS-based Authentication of Named Entities [RFC 6698])
might be a good idea for PG. IMO DANE is a great idea in general, but
browser communities do not agree yet (for reasons, often to do with
performance, which I think by and large do not apply to PG).

Possibly. I did briefly look at RPK a few months back, but that was in
the context of a pinned key (i.e. "SSH into Postgres") rather than
with DANE. I feel like I've seen people talking about DANE a lot more
recently? Maybe there'll be momentum for that at some point.

I do think the momentum for DANE is increasing. I think PG could help
in this regard given that widespread use of PG in the public Internet,
w/ WebPKI, is fairly newish development.

DANE has done wonders for email security.

Nico
--

#22Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Nico Williams (#21)
[oauth] SASL mechanisms

(shamelessly splitting this into its own thread, but also to avoid
further derailment of Neustradamus' tls-exporter conversation)

On Fri, Nov 21, 2025 at 3:15 PM Nico Williams <nico@cryptonector.com> wrote:

For apps like PG I'm much more interested in real OAuth support. But
that's because I use PG in a corporate environment where we use
Kerberos, PKIX, and OAuth for authentication.

Let us know what you think of PG18's OAuth support. We don't have
token binding (whether to the sender or to the channel), but I think
I'd rather put support behind something like an OAUTHDPOP-PLUS than
add bindings to OAUTHBEARER. (Though I still can't figure out whether
mTLS-constrained tokens are dead or not.)

In particular I want the _client_ to be configurable to be smart enough
as to how to fetch the darned OAuth rock the server wants.

libpq can be told to use a custom flow. psql, though, not yet... Only
the device flow for the utilities at the moment.

I'm much
more interested in OAuth for authentication than I am in OAuth for
authorization -- GRANTs and RLS (and/or VIEWs that JOIN authz tables)
are plenty good enough for authz in PG.

I think there might eventually be some interest in the latter, based
on some conversations I've had in the past few months, but I'm not
planning to work on that any time soon. (I think users would expect
central authz changes to take effect immediately, which is not going
to happen.)

--Jacob

#23Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#22)
Re: [oauth] SASL mechanisms

On Fri, Nov 21, 2025 at 03:46:12PM -0800, Jacob Champion wrote:

On Fri, Nov 21, 2025 at 3:15 PM Nico Williams <nico@cryptonector.com> wrote:

For apps like PG I'm much more interested in real OAuth support. But
that's because I use PG in a corporate environment where we use
Kerberos, PKIX, and OAuth for authentication.

Let us know what you think of PG18's OAuth support. We don't have
token binding (whether to the sender or to the channel), but I think
I'd rather put support behind something like an OAUTHDPOP-PLUS than
add bindings to OAUTHBEARER. (Though I still can't figure out whether
mTLS-constrained tokens are dead or not.)

I've not looked in detail yet, but I got the impression that the user
has to fetch the token on their own and provide it to the PG client --
if so that is monumentally unfriendly by comparison to, e.g., Kerberos.

As for mTLS, I'd love to use it, but I need to be able to support PKINIT
SANs and/or rfc822Name SANs and/or UPN SANs. Apps that support client
certificates invariably do so very poorly. Ideally there would be
set_config-like (but not settable in SQL w/o privs) parameters with all
the details of:

- the client certificate (if used)
- all the claims of the OAuth token (if used)
- the Kerberos principal name (if used)
- ...

and ideally then I could use something SECURITY DEFINER functions to SET
SESSION ROLE to assume the desired role (having first "logged in" to a
role with no grants). This would let me manage pg_hba/pg_ident mappings
how I need to rather than how PG offers.

Heck, one could see using SECURITY DEFINER functions to implement many
client authentication mechanisms (possibly ussing pggggg-crypto, or
other extensions) and do SET SESSION ROLE to complete successful logins.

In particular I want the _client_ to be configurable to be smart enough
as to how to fetch the darned OAuth rock the server wants.

libpq can be told to use a custom flow. psql, though, not yet... Only
the device flow for the utilities at the moment.

Basically I have a setup where we have credentials for authenticating to
an STS to get a token with the desired audience. I need the client to
do that: make a token request to the STS. The credential can be what I
like to call a "token granting token", or a Kerberos credential (using
Negotiate), or a KSAT, or a GSAT. I'm willing to provide a library to
fetch the token (I have one that implements all those options), but psql
(and libpq) has to support using it.

I'm much
more interested in OAuth for authentication than I am in OAuth for
authorization -- GRANTs and RLS (and/or VIEWs that JOIN authz tables)
are plenty good enough for authz in PG.

I think there might eventually be some interest in the latter, based
on some conversations I've had in the past few months, but I'm not
planning to work on that any time soon. (I think users would expect
central authz changes to take effect immediately, which is not going
to happen.)

What do you mean? GRANTs and RLS (and ...) all work today. All I need
is for the server to map a `sub` claim (or some other claim I specify in
a config file) to a ROLE, pg_hba.conf/pg_ident.conf style (or better),
just as with Kerberos. Yes, subject identifying claims are optional,
but for corporate network use it's all I need and all I want.

Fine-grained access control via OAuth is a) not really a practical thing
in general, b) decidedly not practical for a high-performance RDBMS. I
recommend not bothering to try.

Nico
--

#24Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#22)
Re: [oauth] SASL mechanisms

Also, we do have custom claims (we should publish a spec and register
them at IANA...) for very coarse-grained authorization that amounts to
an application-level firewall logic that lets us isolate workloads by
type (think prod vs QA vs dev, but also other things).

No OAuth library on the server side can get that right today (we'd have
to contribute to them, which, ok, it's doable, but it takes time). This
is one reason that I want to get each claim as a config item I can
access in SQL code.

Nico
--

#25* Neustradamus *
neustradamus@hotmail.com
In reply to: Nico Williams (#13)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

Hello Nico,

Thanks for your answer!

Links of XEPs are here to confirm that "tls-exporter" is needed and already used.

XEPs are already supported by a lot of projects/softwares/companies in production, for example on GitHub, we can see:
- https://github.com/search?q=XEP-0480+-repo%3Axsf%2Fxeps+-repo%3Axsf%2Fxep-attic+-repo%3Axsf%2Fxmpp.org&amp;type=code
- https://github.com/search?q=XEP-0388+-repo%3Axsf%2Fxeps+-repo%3Axsf%2Fxep-attic+-repo%3Axsf%2Fxmpp.org&amp;type=code
- https://github.com/search?q=XEP-0440+-repo%3Axsf%2Fxeps+-repo%3Axsf%2Fxep-attic+-repo%3Axsf%2Fxmpp.org&amp;type=code
- https://github.com/search?q=XEP-0474+-repo%3Axsf%2Fxeps+-repo%3Axsf%2Fxep-attic+-repo%3Axsf%2Fxmpp.org&amp;type=code

At the same time, about these XEPs, it is the base of the "draft-melnikov-sasl2" done by Alexey Melnikov (author of several RFCs), that you know of course:
- https://datatracker.ietf.org/doc/html/draft-melnikov-sasl2
- https://datatracker.ietf.org/person/Alexey%20Melnikov

Several people would like to deprecate "tls-server-end-point" (RFC 5929) like Simon Josefsson (author of several RFCs), that you know of course, because RFC 9266 exists since July 2022:
- https://mailarchive.ietf.org/arch/msg/kitten/zpesKSHsiuy1RvhPlbSUGajLbKQ/
- https://datatracker.ietf.org/person/Simon%20Josefsson

For example, he is the GNU SASL maintainer and he does not want to add tls-server-end-point support:
- https://gitlab.com/gsasl/gsasl/-/issues/13

Other talks about tls-server-end-point:
- https://mailarchive.ietf.org/arch/browse/kitten/?q=tls-server-end-point&amp;gbt=1&amp;index=
- https://mail.jabber.org/hyperkitty/search?count=200&amp;q=tls-server-end-point&amp;page=1&amp;mlist=standards%40xmpp.org&amp;sort=date-asc
- https://mailarchive.ietf.org/arch/browse/tls/?q=tls-server-end-point&amp;gbt=1&amp;index=

So it is really important to support "tls-exporter".

Regards,

Neustradamus

________________________________________
From: Nico Williams <nico@cryptonector.com>
Sent: Friday, November 21, 2025 18:32
To: * Neustradamus *
Cc: PostgreSQL Hackers
Subject: Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Thu, Nov 20, 2025 at 08:58:54PM +0000, * Neustradamus * wrote:

- XEP-0388: Extensible SASL Profile: https://xmpp.org/extensions/xep-0388.html
- XEP-0440: SASL Channel-Binding Type Capability: https://xmpp.org/extensions/xep-0440.html
- XEP-0474: SASL SCRAM Downgrade Protection: https://xmpp.org/extensions/xep-0474.html
- XEP-0480: SASL Upgrade Tasks: https://xmpp.org/extensions/xep-0480.html

Why are XEPs relevant to PG?

#26Nico Williams
nico@cryptonector.com
In reply to: * Neustradamus * (#25)
Re: RFC 9266: Channel Bindings for TLS 1.3 support

On Sun, Nov 23, 2025 at 01:44:18AM +0000, * Neustradamus * wrote:

Links of XEPs are here to confirm that "tls-exporter" is needed and
already used.

How are XEPs relevant to PG?

Several people would like to deprecate "tls-server-end-point" (RFC
5929) like Simon Josefsson (author of several RFCs), that you know of
course, because RFC 9266 exists since July 2022:

I responded to that. Simon did not respond to my last message. Silence
might denote acquiescence, or it might not, but at any rate there is
currently no effort to obsolete TSEP.

For example, he is the GNU SASL maintainer and he does not want to add
tls-server-end-point support:

That's his right.

So it is really important to support "tls-exporter".

I don't disagree with that. It's not because TSEP might get obsoleted.
One issue that arises is that if you support more than one kind of CB
then you need to be able to negotiate it (for some value of negotiation
anyways; if the server doesn't want the client's choice, you can just
fail, but de minimis you really need to be able to tell the user why
authentication failed).

Nico
--

#27Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Nico Williams (#23)
Re: [oauth] SASL mechanisms

On Fri, Nov 21, 2025 at 9:24 PM Nico Williams <nico@cryptonector.com> wrote:

I've not looked in detail yet, but I got the impression that the user
has to fetch the token on their own and provide it to the PG client --
if so that is monumentally unfriendly by comparison to, e.g., Kerberos.

You provide a client ID and libpq runs a Device Authorization flow.
It's not machine-friendly (you need custom code for that) and our lack
of token caching in PG18 is certainly not user-friendly, but we don't
completely throw you to the wolves. No one is copy-pasting tokens
around.

As for mTLS, I'd love to use it, but I need to be able to support PKINIT
SANs and/or rfc822Name SANs and/or UPN SANs. Apps that support client
certificates invariably do so very poorly. Ideally there would be
set_config-like (but not settable in SQL w/o privs) parameters with all
the details of:

- the client certificate (if used)
- all the claims of the OAuth token (if used)

OAuth validators can also be Postgres extensions, so this is at least
technically feasible to retrieve, though I'm not yet understanding why
you need set_config() functionality. And the sslinfo extension should
be able to give you the SANs (though whether they're in a form that's
easy to use without too much trouble, I don't know).

- the Kerberos principal name (if used)

That should be in pg_stat_gssapi.

and ideally then I could use something SECURITY DEFINER functions to SET
SESSION ROLE to assume the desired role (having first "logged in" to a
role with no grants). This would let me manage pg_hba/pg_ident mappings
how I need to rather than how PG offers.

I mean, nothing here _looks_ impossible at first read, with PG18. Easy
for me to say that if I don't have to write the code, I guess. What
you describe isn't the out-of-the-box feature set, but I think it's
possible.

Basically I have a setup where we have credentials for authenticating to
an STS to get a token with the desired audience. I need the client to
do that: make a token request to the STS. The credential can be what I
like to call a "token granting token", or a Kerberos credential (using
Negotiate), or a KSAT, or a GSAT. I'm willing to provide a library to
fetch the token (I have one that implements all those options), but psql
(and libpq) has to support using it.

libpq will let you plug in your own code. psql doesn't (yet).

That said, OAUTHBEARER doesn't give you either a resource indicator
(i.e. RFC 8707) or an audience ID, so implementing Token Exchange is
maybe not very straightforward yet. At least not without out-of-band
knowledge. But I'm not well-versed in RFC 8693, so I may be clueless
there.

As for working with an STS in general, I think we're going to need
Token Exchange ourselves for postgres_fdw at some point. And possibly
pgbouncer?

All I need
is for the server to map a `sub` claim (or some other claim I specify in
a config file) to a ROLE, pg_hba.conf/pg_ident.conf style (or better),

A validator can do that today [1]https://www.postgresql.org/docs/18/oauth-validator-design.html#OAUTH-VALIDATOR-DESIGN-USERMAP-DELEGATION. Hopefully "better," since a
validator may optionally map token claims to a role with custom logic.
But you have to write C for that, or find a reputable validator that
does it for you. We don't have a validator implementation in core.

Note that the validator documentation uses "authorization" to refer to
the ident mapping itself, not SQL-level GRANTs. In other words, "is
this user identity authorized to assume this role?"

Fine-grained access control via OAuth is a) not really a practical thing
in general, b) decidedly not practical for a high-performance RDBMS. I
recommend not bothering to try.

We're in violent agreement. :D That's basically what I was trying to
say with my email, but I clearly failed.

Thanks,
--Jacob

[1]: https://www.postgresql.org/docs/18/oauth-validator-design.html#OAUTH-VALIDATOR-DESIGN-USERMAP-DELEGATION

#28Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#27)
Re: [oauth] SASL mechanisms

On Mon, Nov 24, 2025 at 09:33:01AM -0800, Jacob Champion wrote:

On Fri, Nov 21, 2025 at 9:24 PM Nico Williams <nico@cryptonector.com> wrote:

I've not looked in detail yet, but I got the impression that the user
has to fetch the token on their own and provide it to the PG client --
if so that is monumentally unfriendly by comparison to, e.g., Kerberos.

You provide a client ID and libpq runs a Device Authorization flow.
It's not machine-friendly (you need custom code for that) and our lack
of token caching in PG18 is certainly not user-friendly, but we don't
completely throw you to the wolves. No one is copy-pasting tokens
around.

Speaking of which, I should probably write up the file-cache I built at
$WORK for tokens. My scheme is much simpler than the MIT Kerberos /
Heimdal ticket "ccache" schemes.

OAuth comes with batteries not included, unlike Kerberos. We've had to
write a bunch of token-fetching libraries for non-browser apps. And
token caching? Pfft, no one ever thinks about that till it's a problem.
These are things that Kerberos had more than 30 years ago. It's a bit
infuriating. At least it's easy to open-code fetching (and caching)
tokens.

OAuth validators can also be Postgres extensions, so this is at least
technically feasible to retrieve, though I'm not yet understanding why
you need set_config() functionality. And the sslinfo extension should
be able to give you the SANs (though whether they're in a form that's
easy to use without too much trouble, I don't know).

Have you see how PostgREST does it? I want it done kinda like that.

(PostgREST uses `set_config()`, but also it doesn't allow arbitrary SQL
to be sent, so your SQL tiggers and views can trust those
`set_config()`s. But that won't do for PG because no authorization is
needed to call `set_config()`.)

- the Kerberos principal name (if used)

That should be in pg_stat_gssapi.

I'd like it to be something more environmental, like the `TG_*` things
that trigger functions get. Having to JOIN a table for a single item
like this is annoying. What I've done in some cases is to make the
client principal name an actual ROLE name (using a trigger to create it
if need be), which then lets me use `current_user` to get at it in SQL
code.

and ideally then I could use something SECURITY DEFINER functions to SET
SESSION ROLE to assume the desired role (having first "logged in" to a
role with no grants). This would let me manage pg_hba/pg_ident mappings
how I need to rather than how PG offers.

I mean, nothing here _looks_ impossible at first read, with PG18. Easy
for me to say that if I don't have to write the code, I guess. What
you describe isn't the out-of-the-box feature set, but I think it's
possible.

These are things that are needed to make using OAuth painless.

(And Kerberos, and PKIX. Ideally things like `pg_hba`/`pg_ident` could
be SQL-coded rather than having to rely on built-in functionaly only.
And if it was trivial to extract "authorization data" from kerberos (it
does support that, which is the same sort of thing as "claims" in OAuth
land), then we could treat all these things in a fairly unified way.

We use an OAuth claim to indicate the user's Kerberos principal name,
since we started out as a Kerberos shop and need a way to transition
that doesn't break old things. But we don't use `sub` for that. So at
minimum we'd need a way to tell PG which claim has the Kerberos
principal name and then `pg_hba`/`pg_ident` can do the rest.

[...]. I need the client to
do that: make a token request to the STS. [...]

libpq will let you plug in your own code. psql doesn't (yet).

:(

That said, OAUTHBEARER doesn't give you either a resource indicator
(i.e. RFC 8707) or an audience ID, so implementing Token Exchange is
maybe not very straightforward yet. At least not without out-of-band
knowledge. But I'm not well-versed in RFC 8693, so I may be clueless
there.

Resource indicators are nice, but we use single-use FQDNs, so `aud`
(audience) is enough to constrain the token to a whole PG DB in most
cases. That said, `resource=postgresql://...` would be fantastic,
falling back on just `aud=FQDN` if the STS doesn't support `resource`.

As for working with an STS in general, I think we're going to need
Token Exchange ourselves for postgres_fdw at some point. And possibly
pgbouncer?

Almost certainly.

I recommend open-coding it rather than relying on some third party
library. Reasons: portability, control, etc. Open-coding this is
pretty straightforward (I've built one in C that does async I/O in a
CPS-style, letting the caller use their own event loop, but it's not
open source, and it doesn't do WIN32; point is it's possible and not too
hard).

All I need
is for the server to map a `sub` claim (or some other claim I specify in
a config file) to a ROLE, pg_hba.conf/pg_ident.conf style (or better),

A validator can do that today [1]. Hopefully "better," since a
validator may optionally map token claims to a role with custom logic.
But you have to write C for that, or find a reputable validator that
does it for you. We don't have a validator implementation in core.

Hmmm, I don't mind writing one in C, but there is a better way based on
how PostgREST does it (see above).

Imagine that we had set-only session-level `set_config()`s, and/or ones
that require privilege. Then authen. mechanisms can set a bunch to
describe the credential used. And then there could be a "session begin
trigger"-like function that the DB owner could specify to the rest of
whatever they want done, up to and including [optionally] `SET SESSION
ROLE`.

Note that the validator documentation uses "authorization" to refer to
the ident mapping itself, not SQL-level GRANTs. In other words, "is
this user identity authorized to assume this role?"

Got it.

Fine-grained access control via OAuth is a) not really a practical thing
in general, b) decidedly not practical for a high-performance RDBMS. I
recommend not bothering to try.

We're in violent agreement. :D That's basically what I was trying to
say with my email, but I clearly failed.

Gotcha, phew! :)

Thanks for the details,

Nico
--

#29Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Nico Williams (#28)
Re: [oauth] SASL mechanisms

On Mon, Nov 24, 2025 at 10:54 AM Nico Williams <nico@cryptonector.com> wrote:

OAuth comes with batteries not included, unlike Kerberos.

Yes. :/

OAuth validators can also be Postgres extensions, so this is at least
technically feasible to retrieve, though I'm not yet understanding why
you need set_config() functionality. And the sslinfo extension should
be able to give you the SANs (though whether they're in a form that's
easy to use without too much trouble, I don't know).

Have you see how PostgREST does it? I want it done kinda like that.

I could see us eventually pulling out the user's claims (whether from
Kerberos or OAuth, or maybe generically mapped from an identity) into
a central API. That way validators wouldn't have to reinvent the wheel
each time.

That should be in pg_stat_gssapi.

I'd like it to be something more environmental, like the `TG_*` things
that trigger functions get. Having to JOIN a table for a single item
like this is annoying. What I've done in some cases is to make the
client principal name an actual ROLE name (using a trigger to create it
if need be), which then lets me use `current_user` to get at it in SQL
code.

As long as you're just looking for the "single" principal that the
database considers to represent the user, we have system_user now.
It's not complex enough to handle multi-factor situations, though,
like when you have both an OAuth token and a client cert. For that you
still need sslinfo.

authn_id itself (which is the internal implementation of system_user)
could be viewed as the base of a more general claims system, I
suppose.

We use an OAuth claim to indicate the user's Kerberos principal name,
since we started out as a Kerberos shop and need a way to transition
that doesn't break old things. But we don't use `sub` for that. So at
minimum we'd need a way to tell PG which claim has the Kerberos
principal name and then `pg_hba`/`pg_ident` can do the rest.

This is what the validator API lets you do today. It's just not done
in SQL (unless of course you write a validator that lets you write
SQL).

libpq will let you plug in your own code. psql doesn't (yet).

:(

I'm trying to take a small step towards that in PG19, if you don't
mind overriding link paths. Generic client-side plugins are probably
too ambitious to turn around in a couple of months; I need a solid
proposal for that and I don't have one yet.

(I don't want this to be a CVE factory. There are a bunch of security
conventions around the server modules that users have gotten used to,
but if I inject those conventions into libpq they will affect a bunch
of people who have never had to think about this before.)

Resource indicators are nice, but we use single-use FQDNs, so `aud`
(audience) is enough to constrain the token to a whole PG DB in most
cases. That said, `resource=postgresql://...` would be fantastic,
falling back on just `aud=FQDN` if the STS doesn't support `resource`.

Yeah, though we'd probably need to outright prohibit query strings in
our resource implementation (postgres://host/db?host=other-host looks
like a nightmare to me). In any case, I think we're going to need to
wait for better authorization server support for that sort of thing
before it goes into our builtin flow.

As for working with an STS in general, I think we're going to need
Token Exchange ourselves for postgres_fdw at some point. And possibly
pgbouncer?

Almost certainly.

I recommend open-coding it rather than relying on some third party
library.

We are well-versed in that by now :)

Imagine that we had set-only session-level `set_config()`s, and/or ones
that require privilege. Then authen. mechanisms can set a bunch to
describe the credential used. And then there could be a "session begin
trigger"-like function that the DB owner could specify to the rest of
whatever they want done, up to and including [optionally] `SET SESSION
ROLE`.

If anyone else is reading along, I'd be interested to see what kind of
appetite there is for a generic mechanism like this? It sounds like a
decent idea to me, but I'm not sure how big the audience for it would
be.

--Jacob

#30Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#29)
Re: [oauth] SASL mechanisms

On Tue, Nov 25, 2025 at 09:19:29AM -0800, Jacob Champion wrote:

On Mon, Nov 24, 2025 at 10:54 AM Nico Williams <nico@cryptonector.com> wrote:

OAuth comes with batteries not included, unlike Kerberos.

Yes. :/

It's very sad and annoying. Mangement wants off Kerberos, but the
amount of work to do for that is enormous. I'm sure the folks at
Microsoft have it much worse because they really need a GSS-API (SSPI)
mechanism that can do key exchange _and_ authentication.

Have you see how PostgREST does it? I want it done kinda like that.

I could see us eventually pulling out the user's claims (whether from
Kerberos or OAuth, or maybe generically mapped from an identity) into
a central API. That way validators wouldn't have to reinvent the wheel
each time.

But I want it _now_ not eventually :)

(And... I don't have time to contribute this, plus I've tried to
contribute to PG before and got my patches into two commitfests, but the
amount of energy needed to contribute to PG is too high. My
contribution was for `ALWAYS DEFERRED` for constraints so that users
cannot make constraints `IMMEDIATE` that were intended to be deferred.)

I'd like it to be something more environmental, like the `TG_*` things
[...]

As long as you're just looking for the "single" principal that the
database considers to represent the user, we have system_user now.

TIL. Since I map to ROLEs using pg_ident, I hadn't needed to know this.
But I can see this being very useful.

It's not complex enough to handle multi-factor situations, though,
like when you have both an OAuth token and a client cert. For that you
still need sslinfo.

Sure. For client certs we _really_ need SANs. Almost every app that
supports client certs only supports using the CN from the cert's name --
this is terrible.

This gets me right back to wanting discrete environmental elements for
each part of the client's credential(s):

- jwt_claim_<claim> (value of <claim> in JWT)

- gss_mechanism (string? containing OID?)
- gss_client_principal (string)

(If MIT Kerberos and/or Heimdal were good at implementinff RFC 6680
then we could have claim-like things [think Kerberos authorization
data elements] here as well.)

- client_cert (blob containing DER-encoding of cert)
- client_anchor (name of root CA the client cert chained to)
- client_cert_dn_<attribute> (value of that attribute of the DN [they can be multi-valued though!])
- client_cert_rfc822Name (rfc822Name SAN [one can have more than one])
- client_cert_PKINIT (PKINIT SAN [one can have more than one])
- client_cert_UPN (UPN SAN [one can have more than one])
- etc.

Resource indicators are nice, but we use single-use FQDNs, so `aud`
(audience) is enough to constrain the token to a whole PG DB in most
cases. That said, `resource=postgresql://...` would be fantastic,
falling back on just `aud=FQDN` if the STS doesn't support `resource`.

Yeah, though we'd probably need to outright prohibit query strings in
our resource implementation (postgres://host/db?host=other-host looks
like a nightmare to me). In any case, I think we're going to need to
wait for better authorization server support for that sort of thing
before it goes into our builtin flow.

Authorization servers are external. You don't need to wait for them.

I recommend open-coding it rather than relying on some third party
library.

We are well-versed in that by now :)

Sad. C is such a terrible language and ecosystem.

Imagine that we had set-only session-level `set_config()`s, and/or ones
that require privilege. Then authen. mechanisms can set a bunch to
describe the credential used. And then there could be a "session begin
trigger"-like function that the DB owner could specify to the rest of
whatever they want done, up to and including [optionally] `SET SESSION
ROLE`.

If anyone else is reading along, I'd be interested to see what kind of
appetite there is for a generic mechanism like this? It sounds like a
decent idea to me, but I'm not sure how big the audience for it would
be.

Please folks speak up for this! :)

(This ties into the parallel thread on RESETing the session role.)

Nico
--

#31Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Nico Williams (#30)
Re: [oauth] SASL mechanisms

On Tue, Nov 25, 2025 at 9:40 AM Nico Williams <nico@cryptonector.com> wrote:

I could see us eventually pulling out the user's claims (whether from
Kerberos or OAuth, or maybe generically mapped from an identity) into
a central API. That way validators wouldn't have to reinvent the wheel
each time.

But I want it _now_ not eventually :)

(And... I don't have time to contribute this, plus I've tried to
contribute to PG before and got my patches into two commitfests, but the
amount of energy needed to contribute to PG is too high.

Yeah, lowering the barrier to entry is a perennial topic...

Authorization servers are external. You don't need to wait for them.

We can implement to spec, but real-world testing gets difficult if no
one else does. I'm not really comfortable blazing a trail there.

Imagine that we had set-only session-level `set_config()`s, and/or ones
that require privilege. Then authen. mechanisms can set a bunch to
describe the credential used. And then there could be a "session begin
trigger"-like function that the DB owner could specify to the rest of
whatever they want done, up to and including [optionally] `SET SESSION
ROLE`.

If anyone else is reading along, I'd be interested to see what kind of
appetite there is for a generic mechanism like this? It sounds like a
decent idea to me, but I'm not sure how big the audience for it would
be.

Please folks speak up for this! :)

Thread bump, in the hopes that we ran into the Thanksgiving lull.

Also, you may be interested in a half-baked proposal [1]/messages/by-id/CAOYmi+mrGg+n_X2MOLgeWcj3v_M00gR8uz_D7mM8z=dX1JYVbg@mail.gmail.com to load
custom OAuth flows for psql et al.

--Jacob

[1]: /messages/by-id/CAOYmi+mrGg+n_X2MOLgeWcj3v_M00gR8uz_D7mM8z=dX1JYVbg@mail.gmail.com

#32Nico Williams
nico@cryptonector.com
In reply to: Jacob Champion (#31)
Re: [oauth] SASL mechanisms

On Tue, Dec 09, 2025 at 01:18:43PM -0800, Jacob Champion wrote:

On Tue, Nov 25, 2025 at 9:40 AM Nico Williams <nico@cryptonector.com> wrote:

(And... I don't have time to contribute this, plus I've tried to
contribute to PG before and got my patches into two commitfests, but the
amount of energy needed to contribute to PG is too high.

Yeah, lowering the barrier to entry is a perennial topic...

I had to write my own tool to do something like bisect-rebase to rebase
across thousands of commits...