Обсуждение: Custom oauth validator options
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.
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
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.
> 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
> 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.
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
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
> 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.
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...?
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.
> 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?
Вложения
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
> 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.
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
> 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.