Обсуждение: Custom oauth validator options

Поиск
Список
Период
Сортировка

Custom oauth validator options

От
Zsolt Parragi
Дата:
Hello hackers,

The current OAuth code allows validators to add custom validation
logic, but does not allow them to introduce custom
authentication-related parameters in the place where they belong:
pg_hba.conf. As a workaround, both pg_oidc_validator and
postgres-keycloak-oauth-validator (and likely others; these are simply
the two I know of) rely on GUC variables instead.

I see two issues with this:

1. Configuration for OAuth validation ends up split across two
locations: issuer/scope and a few other parameters are defined in
pg_hba.conf, while custom parameters must be set in postgresql.conf.

2. We have received multiple questions asking how to configure
multiple OIDC servers with different parameter sets. I am not sure how
common it is to use multiple OAuth providers with a single PostgreSQL
instance, but the question is certainly reasonable.

Given this, I would like to ask what you think about making
pg_hba.conf extensible. At present, option parsing is hardcoded in
parse_hba_auth_opt, and any unknown parameter triggers an error at the
end of the function.

I can see a few possible approaches:

a. Add an OAuth-specific hook that allows injecting additional
option-parsing logic into this function, as part of the existing
OAuthValidatorCallbacks. This could be scoped to the validator used on
the specific HBA line, even if multiple validators are loaded.
b. Allow the existing startup callback to supply a list of additional
valid configuration names, with the validation callback responsible
for parsing and validating them.
c. Add a more generic hook usable by any extension. I do not currently
have concrete use cases outside OAuth, but perhaps others do.

I would be interested in your thoughts on whether an improvement in
this area would be useful.

I also have two related questions, which might be addressed as part of
the above or independently:

1. HBA options are parsed sequentially. If validator-specific options
are tied to a particular validator, this implies that validator=...
must appear before its parameters when multiple validators are loaded,
since we cannot otherwise determine which validator is used. Is this
acceptable behavior, or should options be allowed in any order?

2. If a validator introduces many options, an HBA line could become
very long and hard to read. Would it make sense to allow loading the
parameters for a given line from a separate file? This might already
be useful today: for example, if a long issuer URL is repeated across
several HBA lines, it could instead be defined once in an external
file and referenced multiple times.



Re: Custom oauth validator options

От
Jacob Champion
Дата:
Sorry for missing this thread!

On Tue, Dec 2, 2025 at 5:06 AM Zsolt Parragi <zsolt.parragi@percona.com> wrote:
> 1. Configuration for OAuth validation ends up split across two
> locations: issuer/scope and a few other parameters are defined in
> pg_hba.conf, while custom parameters must be set in postgresql.conf.

Yeah. (This has come up before a couple of times that I know of, in
the context of pg_hba and pg_ident splitting important configuration
between them [1], and in the context of SNI's proposed pg_hosts config
[2].)

> 2. We have received multiple questions asking how to configure
> multiple OIDC servers with different parameter sets. I am not sure how
> common it is to use multiple OAuth providers with a single PostgreSQL
> instance, but the question is certainly reasonable.

What kinds of parameters? Having a motivating use case would be
helpful; HBA isn't always as flexible as people assume and I want to
make sure that we can end with a usable feature.

> Given this, I would like to ask what you think about making
> pg_hba.conf extensible.

Your proposals (and the concerns they raise) seem reasonable enough at
first glance. (I still want a motivating use case, though.)

Honestly, I'd *prefer* that any solution not be OAuth-specific. I
might throw two alternatives onto the pile:

d. Have HBA plug into the GUC system itself

A hypothetical PGC_HBA context would seem to fit nicely between
PGC_SIGHUP and PGC_SU_BACKEND.

e. Subsume HBA, ident, (hosts,) etc. under postgresql.conf

This is my personal white whale. I think pg_hba+ident is no longer fit
for purpose. It makes nonexistent use cases easy and common use cases
unnecessarily difficult. Most people ignore half the columns. New
users are surprised that you can't choose between authentication
options. You have to correlate a bunch of different files with
differing syntaxes to figure out what is going on. Etc, etc.

This is why I bypassed pg_ident for validators, so that they could be
free to do useful stuff while the core caught up. But I didn't intend
to keep them separate forever.

(I'm only halfway serious with (e) -- I don't really intend to drive
your thread straight into a wall. But when I read proposals a-c, I get
the sinking feeling that this *should* be solved in a more radical
way, if we could only agree on a direction...)

Thanks,
--Jacob

[1] https://postgr.es/m/0e0c038ab962c3f6dab00934fe5ae1ae115f44c0.camel%40vmware.com
[2] https://postgr.es/m/CAOYmi%2B%3DZjGJLw8tCkzY88acd%3Dir1r8eAxO-%2B5wXm9gtCUV97Sg%40mail.gmail.com



Re: Custom oauth validator options

От
VASUKI M
Дата:

Hi All,

The core issue,as you said,is that OAuth validators can add custom validation logic,but they can't define their own authentication-related parameters in pg_hba.conf,where they naturally belong.Because of that,validator-specific config ends up pushed into postgresql.conf via GUCs,which feels a bit awkward and scattered.

That leads to the same points you mentioned:

1]OAuth configuration gets split between pg_hba.conf and postgres.conf,which is confusing to reason about.
2]using multiple OIDC/OAuth providers with different parameter sets on a single Postgresql instance is hard(or effectively impossible),even though it's a pretty reasonable use case.

Given the constraints of the current HBA model(and similar issues that recently came up with SNI),I agree that anything involving generic extensibility or nested configuration would be a big hammer and likely too complex.

I also have two related questions, which might be addressed as part of
the above or independently:

1. HBA options are parsed sequentially. If validator-specific options
are tied to a particular validator, this implies that validator=...
must appear before its parameters when multiple validators are loaded,
since we cannot otherwise determine which validator is used. Is this
acceptable behavior, or should options be allowed in any order?

2. If a validator introduces many options, an HBA line could become
very long and hard to read. Would it make sense to allow loading the
parameters for a given line from a separate file? This might already
be useful today: for example, if a long issuer URL is repeated across
several HBA lines, it could instead be defined once in an external
file and referenced multiple times.


So the direction I'm most aligned with is option (b): letting OAuth validator advertise a limited list of additional valid option names for pg_hba.conf,while keeping parsing,ordering rules,and validation firmly in core.That seems like the least spicy option-incremental,OAuth-scoped,and not a redesign of HBA parsing.

Reg. ordering:requiring validator= to appear before validator-specific options feels acceptable to me if this is pursued,since it keeps parsing simple and avoids ambiguity.
Reg very long HBA lines: totally agree this is a real readability issue,but allowing per-line includes or external file feels like a seperate(and much bigger)topic,probably best tackled independently.

Overall, +1 that this limitation is real and worth discussing.I’ll plan to send a patch shortly exploring option (b).

Regards,

Vasuki M
CDAC,Chennai.


 

Re: Custom oauth validator options

От
Zsolt Parragi
Дата:
> What kinds of parameters? Having a motivating use case would be
> helpful; HBA isn't always as flexible as people assume and I want to
> make sure that we can end with a usable feature.

One issue we have is that some providers don't allow users to select
what goes into the subject claim, but do allow users to define custom
claims. Additionally, the subject claim is sometimes a random
generated id, which gets generated on the first login to the client,
and that makes it practically unusable for pg. It would require:

* user trying to login to pg
* getting rejected
* figuring out what's the subject
* adding it to pg ident / some other config
* user can finally login

Instead we decided to let everyone configure which claim they want to
use for user mapping. But because of that, this is a GUC, and they can
only configure it once pre server.

The postgres-keycloak-oauth-validator is in an even worse situation,
they decided to use a long list of GUC parameters[1]. The main reason
is that they use an introspection endpoint for validation instead of
the JWT, so they need multiple parameters for that. Some of these GUCs
seem redundant to me, but some of them are definitely required.

They also have parameters for the client id and debugging - those are
things we are also considering adding to our validator.

> (I'm only halfway serious with (e) -- I don't really intend to drive
> your thread straight into a wall. But when I read proposals a-c, I get
> the sinking feeling that this *should* be solved in a more radical
> way, if we could only agree on a direction...)

I tried to propose simple things that are relatively easy to
implement, and wouldn't change too much at once, so there's a
realistic change for this making into PG19. I'm not against having a
bigger goal, and continuing making it even better after that.

> A hypothetical PGC_HBA context would seem to fit nicely between
> PGC_SIGHUP and PGC_SU_BACKEND.

How would you configure that since the hba lines don't have IDs?
Should we add a "guc_name" parameter to HBA for this or something like
that? I like this idea, it would be fun to implement and see how it
works, I'm just wondering how users could use it.

[1]:
https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator/blob/5fceacf53c3d86fbbe18dab0341311855a89fe6a/src/kc_validator.c#L741



Re: Custom oauth validator options

От
Zsolt Parragi
Дата:
> Overall, +1 that this limitation is real and worth discussing.I’ll plan to send a patch shortly exploring option (b).

Personally I would go with either (a) or (c), and I was planning to
clean up / improve / share my (c) patch as a second attempt for this
thread, if it didn't receive any replies. I can still do that, so that
we have multiple test implementations. (b) seemed a not as nice design
to me, but maybe you find a better way to implement it than I did.

Also now I really like the idea of the PGC_HBA, if there's a way for
users to configure it without depending on line numbers or other
easy-to-change details.



Re: Custom oauth validator options

От
Jacob Champion
Дата:
On Tue, Dec 16, 2025 at 10:30 PM VASUKI M <vasukianand0119@gmail.com> wrote:
> Overall, +1 that this limitation is real and worth discussing.I’ll plan to send a patch shortly exploring option (b).

Thanks!

> Reg very long HBA lines: totally agree this is a real readability issue,but allowing per-line includes or external
filefeels like a seperate(and much bigger)topic,probably best tackled independently. 

I forgot to mention in my reply to Zsolt, but we've supported inline
inclusions in HBA for a few releases now. (I just frequently forget
they exist.)

pg_hba.conf:

    hostssl  all  all  0.0.0.0/0  oauth  @oauth-settings.conf

oauth-settings.conf:

    issuer=https://oauth.example.org/v2
    scope="openid email let-me-into-pg"
    validator=example_org
    map=examplemap

And for smaller annoyances, you can wrap lines with backslash continuation.

I haven't used these new features much, since I forget they exist, so
if there are usability problems in practice please say something so we
can fix it.

--Jacob



Re: Custom oauth validator options

От
Jacob Champion
Дата:
On Wed, Dec 17, 2025 at 1:28 AM Zsolt Parragi <zsolt.parragi@percona.com> wrote:
> Instead we decided to let everyone configure which claim they want to
> use for user mapping. But because of that, this is a GUC, and they can
> only configure it once pre server.

We're getting closer; I agree that this needs to be more flexible than
it is, and I'm on board with a change, but I'm still missing the
"killer app". What's the case where a user has multiple HBA lines that
all want to use unrelated claims for authentication to one Postgres
cluster? Is this multi-tenancy, or...?

> I tried to propose simple things that are relatively easy to
> implement, and wouldn't change too much at once, so there's a
> realistic change for this making into PG19. I'm not against having a
> bigger goal, and continuing making it even better after that.

Absolutely -- that's a tried and true strategy. No objections to that.

But I also didn't want to stay silent on my longer-term goals here.
That way (hopefully), no one's surprised to find I'm lukewarm on
patches that are extremely OAuth-specific, or that don't give us a way
to improve/evolve later. The additional flexibility of OAuth should
ideally be mirrored in other auth methods when possible.

> > A hypothetical PGC_HBA context would seem to fit nicely between
> > PGC_SIGHUP and PGC_SU_BACKEND.
>
> How would you configure that since the hba lines don't have IDs?
> Should we add a "guc_name" parameter to HBA for this or something like
> that? I like this idea, it would be fun to implement and see how it
> works, I'm just wondering how users could use it.

I hadn't thought it through very far; my initial impression was that
we'd need some sort of additional syntax. But I keep coming back to
httpd-style configs and then I choose something else from my TODO list
to focus on. :) See also the old conversation regarding LDAP hba/ident
[1].

On Wed, Dec 17, 2025 at 1:36 AM Zsolt Parragi <zsolt.parragi@percona.com> wrote:
> Personally I would go with either (a) or (c), and I was planning to
> clean up / improve / share my (c) patch as a second attempt for this
> thread, if it didn't receive any replies. I can still do that, so that
> we have multiple test implementations.

The more the merrier!

Thanks,
--Jacob

[1] https://postgr.es/m/CAOuzzgpFpuroNRabEvB9kST_TSyS2jFicBNoXvW7G2pZFixyBw%40mail.gmail.com



Re: Custom oauth validator options

От
Zsolt Parragi
Дата:
> I forgot to mention in my reply to Zsolt, but we've supported inline
> inclusions in HBA for a few releases now. (I just frequently forget
> they exist.)

Thanks, I didn't know about that feature, that solves half of my problem.

> What's the case where a user has multiple HBA lines that
> all want to use unrelated claims for authentication to one Postgres
> cluster? Is this multi-tenancy, or...?

For configuring the authn matching yes, the use case is multitenancy.

But for some other variables that we didn't implement yet, this could
be useful even without multitenancy.

One thing I mentioned in the previous email is the client id
validation. A practical use case of that would be restricting which
oauth clients can login to which database. I can't use a SUSET
variable with a check restricting it to ALTER DATABASE, because
database level variables are not yet available during the oauth
validator callback. I could use a login event trigger, but that seems
like a bad hack to me.



Re: Custom oauth validator options

От
VASUKI M
Дата:


On Thu, Dec 18, 2025 at 12:31 AM Jacob Champion <jacob.champion@enterprisedb.com> wrote:
On Wed, Dec 17, 2025 at 1:28 AM Zsolt Parragi <zsolt.parragi@percona.com> wrote:
> Instead we decided to let everyone configure which claim they want to
> use for user mapping. But because of that, this is a GUC, and they can
> only configure it once pre server.

We're getting closer; I agree that this needs to be more flexible than
it is, and I'm on board with a change, but I'm still missing the
"killer app". What's the case where a user has multiple HBA lines that
all want to use unrelated claims for authentication to one Postgres
cluster? Is this multi-tenancy, or...?

Beyond multitenancy,per -HBA OAuth  cases where options are needed for safe provider migration[blue/green],per-database security policies,mixed Human/machine authentication[JWT/Introspection] and incident-response scenarios -all global GUCs are too coarse.

See also the old conversation regarding LDAP hba/ident
[1]

[1] https://postgr.es/m/CAOuzzgpFpuroNRabEvB9kST_TSyS2jFicBNoXvW7G2pZFixyBw%40mail.gmail.com

 Thanks, Will go through it.

Regards,

Vasuki M
CDAC,Chennai.

Re: Custom oauth validator options

От
Zsolt Parragi
Дата:
> Personally I would go with either (a) or (c), and I was planning to
> clean up / improve / share my (c) patch as a second attempt for this
> thread, if it didn't receive any replies. I can still do that, so that
> we have multiple test implementations.

I attached the patch. It modifies one of the existing oauth_validator
tests to showcase how it works, but in theory it isn't dependent on
oauth. It however requires shared_preload_libraries (that is common
for all options), maybe oauth_validator_libraries could imply that?

Вложения

Re: Custom oauth validator options

От
Jacob Champion
Дата:
On Thu, Dec 18, 2025 at 1:08 AM Zsolt Parragi <zsolt.parragi@percona.com> wrote:
>
> It however requires shared_preload_libraries (that is common
> for all options), maybe oauth_validator_libraries could imply that?

Haven't looked at the patch yet, but I think most people probably want
to use session_preload_libraries, not shared_preload_libraries, so
that a security update to their validator doesn't require a restart of
the cluster.

If a particular validator implementation requires shared preload, so
be it; but I don't think we want to force it. Might be more reason to
look into the GUC system?

--Jacob



Re: Custom oauth validator options

От
Zsolt Parragi
Дата:
> Might be more reason to look into the GUC system?

I am already thinking about that, I have some ideas for a proof of
concept, but no working prototype yet. But without requiring
shared_preload_libraries, we can't do early error reporting during
postmaster startup about custom parameters. Is that okay? GUCs already
work this way, and this could be a bit safer (reporting unknown
parameters/refusing to proceed during login, when we can completely
parse all parameters), but it would be different compared to how
pg_hba is handled currently.



Re: Custom oauth validator options

От
Jacob Champion
Дата:
On Thu, Dec 18, 2025 at 10:28 AM Zsolt Parragi
<zsolt.parragi@percona.com> wrote:
> But without requiring
> shared_preload_libraries, we can't do early error reporting during
> postmaster startup about custom parameters. Is that okay?

I think I need to do more staring at the intersection of GUC
registration and session_preload_libraries, because my memory of the
order of operations was faulty. I won't be able to do that before the
holidays, most likely.

--Jacob



Re: Custom oauth validator options

От
Zsolt Parragi
Дата:
> I think I need to do more staring at the intersection of GUC
> registration and session_preload_libraries, because my memory of the
> order of operations was faulty. I won't be able to do that before the
> holidays, most likely.

Maybe I'm missing something, but why do we need
session_preload_libraries? oauth_validator_libraries is processed
earlier, it can already define sighup GUCs, it should also work with a
new level around that. I assume that if postgres gets another
authentication plugin point later, it will be executed around the same
place, during authentication, so that also shouldn't be an issue.

The question is if non-validator libraries should be able to define
PGC_HBA variables. If yes, then either

* we don't validate that all HBA variables are valid - if somebody
made a typo, we can't detect it
* we add a sighup guc with a manual whitelist
* require shared preload libraries or oauth_validator_libraries,
because those are loaded before or during authentication
* require session_preload_libraries. We proceed with authentication
even with unresolved HBA variables, but abort the connection if there
are still unknown parameters after loading session preload.