Proposal: Supporting URI SAN in Certificate Authentication
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t139150psql -h localhost -U postgresBuilt from patchset v8 (message #8), September 17, 2026 at 10:22 AM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t139150_8 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t139150_8 && git checkout t139150_8Patchset v8 (message #8) is on t139150_8
Hello PostgreSQL Hackers,
I’d like to open the discussion about adding support for URI Subject
Alternative Names (URI SAN) in PostgreSQL certificate authentication.
Today, PostgreSQL only supports extracting identity from the certificate
Subject (CN or full DN). This limits interoperability with modern workload
identity systems that rely on URI-based identities:
* Cockroach Labs added URI SAN support for SPIFFE/SPIRE:
https://www.cockroachlabs.com/blog/zero-trust-database-authentication-spiffe-spire
* The IETF WIMSE Working Group is standardizing URI-based workload
identities: https://datatracker.ietf.org/group/wimse/about
Proposal: Allow certificate authentication to use URI SAN entries as the
client identity (e.g. via a clientname=uri option in pg_hba.conf), in
addition to the existing CN/DN options.
Questions:
* Is there interest in this feature from the community?
* Are there known objections or prior discussions around using SAN (and
specifically URI SAN) for identity in PostgreSQL auth?
* How should multiple URI SAN entries be handled (first match, require
uniqueness, mapping rules, etc.)?
Thanks,
Olivier Cano
On 3/27/26 20:20, olivier cano wrote:
Proposal: Allow certificate authentication to use URI SAN entries as the
client identity (e.g. via a clientname=uri option in pg_hba.conf), in
addition to the existing CN/DN options.Questions:
* Is there interest in this feature from the community?
This was recently requested for the pgBackRest project [1]https://github.com/pgbackrest/pgbackrest/issues/2765 so there does
seem to be some interest from users, at least.
The user decided to fallback to using CNs since Postgres support does
not seem like it will happen soon and we are unlikely to add it in
pgBackRest until it is supported by Postgres.
Regards,
-David
Thanks, Olivier, for proposing it, and thanks, David, for replying (I had
lost this thread before).
I would also like to express strong support for this proposal.
As SPIFFE/SPIRE adoption continues to grow, having native support for URI
SANs in PostgreSQL certificate authentication would be a huge step forward
for modern workload identity management. Both SPIFFE and SPIRE are
graduated CNCF projects, and there is already clear interest in integrating
them across the cloud-native ecosystem.
For instance, within CloudNativePG (also a CNCF project), there is a strong
interest in supporting workload identities provided by SPIFFE/SPIRE:
https://github.com/cloudnative-pg/cloudnative-pg/discussions/6421
Having native support at the PostgreSQL level would make zero-trust
identity integration much cleaner and more seamless across operators and
surrounding tools.
Ciao,
Gabriele
On Fri, 21 Aug 2026 at 11:35, David Steele <david@pgbackrest.org> wrote:
On 3/27/26 20:20, olivier cano wrote:
Proposal: Allow certificate authentication to use URI SAN entries as the
client identity (e.g. via a clientname=uri option in pg_hba.conf), in
addition to the existing CN/DN options.Questions:
* Is there interest in this feature from the community?This was recently requested for the pgBackRest project [1] so there does
seem to be some interest from users, at least.The user decided to fallback to using CNs since Postgres support does
not seem like it will happen soon and we are unlikely to add it in
pgBackRest until it is supported by Postgres.Regards,
-David
--
Gabriele Bartolini
VP, Chief Architect, Kubernetes
enterprisedb.com / Melbourne, Australia
Il giorno ven 27 mar 2026 alle ore 14:21 olivier cano <
kindermoumoute@gmail.com> ha scritto:
* How should multiple URI SAN entries be handled (first match, require
uniqueness, mapping rules, etc.)?Hello,
I think teh best approach is to keep it simple and explicit. When a
certificate has multiple URI SANs, PostgreSQL should extract all of them
and then try to map each one using the pg_ident.conf rules, same like we do
today with CN or DN.
The key thing is that the client must tell PostgreSQL which user they want
to connect as. Then PostgreSQL looks through all the mappings it found and
checks if any of the SANs map to that requested user. If exactly one SAN
matches the user, we allow the connection. If none match, we reject. If
many SANs map to different users but the client already said which one they
want, that is fine, we just use the right one.
This way we are not guessing. The audit log will show exactly which SAN was
used, not just "some certificate matched". This is important for security
and for tracking what happened.
I think this is better than trying to pick the first match automatically,
because that can be confusing. Different systems might arrange the SANs in
different order, and then the same certfiicate behaves differently. With
explicit matching, everything is clear.
The certificate can still contain many SANs for different purposes - maybe
DNS names for Kubernetes, and URI names for database auth. The
pg_ident.conf rules let you organize this however makes sense for your
setup.
For example, if you have one certificate with three SANs and they all map
to different database users via your rules, the client just needs to say
which user they want, and then it works.
This follows the same logic that already exists with DN.
I will start looking into this approach and propose a patch, we can discuss
more while actually doing it.
Cheers,
Florin
--
* Florin Irion *
* https://www.enterprisedb.com <https://www.enterprisedb.com/>*
On Wed, Aug 26, 2026 at 11:07 AM Florin Irion <irionr@gmail.com> wrote:
* How should multiple URI SAN entries be handled (first match, require uniqueness, mapping rules, etc.)?
The key thing is that the client must tell PostgreSQL which user they want to connect as. Then PostgreSQL looks through all the mappings it found and checks if any of the SANs map to that requested user. If exactly one SAN matches the user, we allow the connection. If none match, we reject. If many SANs map to different users but the client already said which one they want, that is fine, we just use the right one.
I interpreted the question about "first match" to mean: what if many
SANs in the cert map to the *same* database user?
(IMO an implementation of this that ignored pg_ident mapping would be
vetoable without a really, _really_ good reason, so I'm not sure that
branch of the discussion needs to consume much energy.)
I think this is better than trying to pick the first match automatically, because that can be confusing.
I don't understand what you mean here, in the context of our startup
handshake. We don't allow you to omit the database username from the
startup packet, so there couldn't be any guesswork around which DB
role a client meant to connect under.
The pg_ident.conf rules let you organize this however makes sense for your setup.
Sort of. We're currently pretty bad at allowing you to say "or" in the
HBA. So without more design work, I don't think there's going to be a
way to dynamically switch the `clientname` setting from CN to DN to
URI (to email, to other SAN...); you'd have to choose one and stick to
it for a given HBA line.
--Jacob
Thanks Jacob,
Il giorno gio 27 ago 2026 alle ore 00:12 Jacob Champion <
jacob.champion@enterprisedb.com> ha scritto:
I interpreted the question about "first match" to mean: what if many
SANs in the cert map to the *same* database user?
Well that is mainly how the user configures the pg_ident and their SANs, We
can't do much about it, no?
And initially I was looking for 1 to 1 dbuser and SAN, but it should jsut
be dbuser<->ANY SAN (once we find the first one that authenticates the user
the client requests we're good).
I think this is better than trying to pick the first match automatically,
because that can be confusing.I don't understand what you mean here, in the context of our startup
handshake. We don't allow you to omit the database username from the
startup packet, so there couldn't be any guesswork around which DB
role a client meant to connect under.
Correct, I probably just expressed it badly, I was trying to make a point
that the dbuser is requested, so we just need to find a good SAN for it in
order to authenticate it. And based on the previous point, not necessarily
a unique dbuser<->SAN pair.
The pg_ident.conf rules let you organize this however makes sense for
your setup.
Sort of. We're currently pretty bad at allowing you to say "or" in the
HBA. So without more design work, I don't think there's going to be a
way to dynamically switch the `clientname` setting from CN to DN to
URI (to email, to other SAN...); you'd have to choose one and stick to
it for a given HBA line.
Yes, a user can organize the rules in every way they like , but we can not
use different `clientname` in pg_hba, that is still teh same as we have now
with e.g. CN and DN, no?
If we were to change this , it should not be part of this work IMO, no? Or
is there something I'm missing?
Cheers,
Florin
--
* Florin Irion *
* https://www.enterprisedb.com <https://www.enterprisedb.com/>*
On Thu, Aug 27, 2026 at 3:25 AM Florin Irion <irionr@gmail.com> wrote:
Well that is mainly how the user configures the pg_ident and their SANs, We can't do much about it, no?
And initially I was looking for 1 to 1 dbuser and SAN, but it should jsut be dbuser<->ANY SAN (once we find the first one that authenticates the user the client requests we're good).
Right. (I think that's what Olivier was trying to say in the OP.)
Yes, a user can organize the rules in every way they like , but we can not use different `clientname` in pg_hba, that is still teh same as we have now with e.g. CN and DN, no?
It's the "same", I guess, but you can only ever have one Subject, and
CN is a subset of DN. So IMO, it doesn't really make sense to combine
them. But that's not the case for SANs.
If we were to change this , it should not be part of this work IMO, no? Or is there something I'm missing?
I just want to make sure that expectations are set appropriately. If
the desired end goal is that you can authenticate using the standard
Subject match _or_ a number of Subject Alternative Names (which seems
like a very reasonable thing for people to want), v1 of this feature
is unlikely to deliver that without a lot more explicit planning and
design. That's okay with me as long as it's also okay with the people
asking for the feature.
Thanks,
--Jacob
Hi
Here is the first version of the patch to support URI SAN in certificate
authentication (clientname=URI in pg_hba.conf). We can start a discussion
on the actual code now.The patch can also be reviewed on my “postgres”
project fork [1]https://github.com/irionr/postgres/pull/7.
Together with Leonardo Cecchi, CloudNativePG (CNPG) maintainer, we also
tested the patch using the cnpg-i-spiffe plugin[2]https://github.com/leonardoce/cnpg-i-spiffe that he wrote for the
occasion and the generated container image for CloudNativePG [3]https://github.com/leonardoce/postgres-trunk-containers/actions/runs/35070429177. Everything
worked smoothly, and workloads can now authenticate natively with SPIFFE
IDs.
Given that both CloudNativePG and SPIFFE/SPIRE are CNCF projects, we
contacted
Agustín Martínez Fayó, a SPIRE maintainer, to verify the integration between
the two projects and to begin collaborating on the topic. We decided to
strictly allow only a single URI SAN per certificate. This follows the
X509-SVID spec, avoiding weird edge cases with user mapping, and making
connection logging very clear.
Cheers,
Florin
[1]: https://github.com/irionr/postgres/pull/7
[2]: https://github.com/leonardoce/cnpg-i-spiffe
[3]: https://github.com/leonardoce/postgres-trunk-containers/actions/runs/35070429177
https://github.com/leonardoce/postgres-trunk-containers/actions/runs/35070429177