Re: [PoC] Federated Authn/z with OAUTHBEARER - Mailing list pgsql-hackers
From | Antonin Houska |
---|---|
Subject | Re: [PoC] Federated Authn/z with OAUTHBEARER |
Date | |
Msg-id | 4503.1727703521@antos Whole thread Raw |
In response to | Re: [PoC] Federated Authn/z with OAUTHBEARER (Jacob Champion <jacob.champion@enterprisedb.com>) |
Responses |
Re: [PoC] Federated Authn/z with OAUTHBEARER
Re: [PoC] Federated Authn/z with OAUTHBEARER |
List | pgsql-hackers |
Jacob Champion <jacob.champion@enterprisedb.com> wrote: > On Fri, Sep 27, 2024 at 10:58 AM Antonin Houska <ah@cybertec.at> wrote: > > Have you considered sending the token for validation to the server, like this > > > > curl -X GET "https://www.googleapis.com/oauth2/v3/userinfo" -H "Authorization: Bearer $TOKEN" > > In short, no, but I'm glad you asked. I think it's going to be a > common request, and I need to get better at explaining why it's not > safe, so we can document it clearly. Or else someone can point out > that I'm misunderstanding, which honestly would make all this much > easier and less complicated. I would love to be able to do it that > way. > > We cannot, for the same reason libpq must send the server an access > token instead of an ID token. The /userinfo endpoint tells you who the > end user is, but it doesn't tell you whether the Bearer is actually > allowed to access the database. That difference is critical: it's > entirely possible for an end user to be authorized to access the > database, *and yet* the Bearer token may not actually carry that > authorization on their behalf. (In fact, the user may have actively > refused to give the Bearer that permission.) > That's why people are so pedantic about saying that OAuth is an > authorization framework and not an authentication framework. This statement alone sounds as if you missed *authentication*, but you seem to admit above that the /userinfo endpoint provides it ("tells you who the end user is"). I agree that it does. My understanding is that this endpoint, as well as the concept of "claims" and "scopes", is introduced by OpenID, which is an *authentication* framework, although it's built on top of OAuth. Regarding *authorization*, I agree that the bearer token may not contain enough information to determine whether the owner of the token is allowed to access the database. However, I consider database a special kind of "application", which can handle authorization on its own. In this case, the authorization can be controlled by (not) assigning the user the LOGIN attribute, as well as by (not) granting it privileges on particular database objects. In short, I think that *authentication* is all we need. > To illustrate, think about all the third-party web services out there > that ask you to Sign In with Google. They ask Google for permission to > access your personal ID, and Google asks you if you're okay with that, > and you either allow or deny it. Now imagine that I ran one of those > services, and I decided to become evil. I could take my legitimately > acquired Bearer token -- which should only give me permission to query > your Google ID -- and send it to a Postgres database you're authorized > to access. > > The server is supposed to introspect it, say, "hey, this token doesn't > give the bearer access to the database at all," and shut everything > down. For extra credit, the server could notice that the client ID > tied to the access token isn't even one that it recognizes! But if all > the server does is ask Google, "what's the email address associated > with this token's end user?", then it's about to make some very bad > decisions. The email address it gets back doesn't belong to Jacob the > Evil Bearer; it belongs to you. Are you sure you can legitimately acquire the bearer token containing my email address? I think the email address returned by the /userinfo endpoint is one of the standard claims [1]. Thus by returning the particular value of "email" from the endpoint the identity provider asserts that the token owner does have this address. (And that, if "email_verified" claim is "true", it spent some effort to verify that the email address is controlled by that user.) > Now, the token introspection endpoint I mentioned upthread Can you please point me to the particular message? > should give us the required information (scopes, etc.). But Google doesn't > implement that one. In fact they don't seem to have implemented custom > scopes at all in the years since I started work on this feature, which makes > me think that people are probably not going to be able to safely log into > Postgres using Google tokens. Hopefully there's some feature buried > somewhere that I haven't seen. > > Let me know if that makes sense. (And again: I'd love to be proven > wrong. It would improve the reach of the feature considerably if I > am.) Another question, assuming the token verification is resolved somehow: wouldn't it be sufficient for the initial implementation if the client could pass the bearer token to libpq in the connection string? Obviously, one use case is than an application / web server which needs the token to authenticate the user could eventually pass the token to the database server. Thus, if users could authenticate to the database using their individual ids, it would no longer be necessary to store a separate userid / password for the application in a configuration file. Also, if libpq accepted the bearer token via the connection string, it would be possible to implement the authorization as a separate front-end application (e.g. pg_oauth_login) rather than adding more complexity to libpq itself. (I'm learning this stuff on-the-fly, so there might be something naive in my comments.) [1] https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims -- Antonin Houska Web: https://www.cybertec-postgresql.com
pgsql-hackers by date: