Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to Call Function Rather than SET ROLE <user> #529

Closed
davidkuep opened this issue Mar 15, 2016 · 3 comments
Closed

Option to Call Function Rather than SET ROLE <user> #529

davidkuep opened this issue Mar 15, 2016 · 3 comments
Labels
enhancement a feature, ready for implementation

Comments

@davidkuep
Copy link

In Auth.hs lines 74 & 75 appear to be the only place that determine how auth works in the entire system, and it only works by setting role to a role as provided by JWT.

{-| Receives the name of a role and returns a SET ROLE statement -} setRole :: Text -> BS.ByteString setRole r = "set local role " <> cs (pgFmtLit r) <> ";"

If you want to do session authentication, or set a role based on a parameter other than the role provided in JWT, it's very hard because of this. While I understand that one can do session authorization etc outside of Postgres/PostgREST, it would be much, much easier to instead provide a command line option that allowed for a function to be called by the authenticator user, taking no inputs and using the JWT claims exposed by PostgREST for instance, you could include a command line argument that is either --role-auth or --function-auth. The user would then be required to create a function in the schema in which PostgREST was running called postgrest_auth(). This would allow the user full control over login straight from Postgres, they could just write a function to check any auth tables, etc using the claims encoded in the JWT. The function would be required to return void and issue an error if there was an error authenticating the user.

For instance, right now, even if I had a session auth system, it would have to be separate from Postgres etc because the only claim that matters in the JWT is the Role claim, so then I'd have to implement something in Nginx or Redis or something else to handle token revocation etc, it would be easier to, instead of issuing a claim in my JWT called Role, simply issue a claim called sessionid and then look it up and switch into the role listed in the field for that session as long as it wasn't expired. I don't think it would add much overhead either. Another way to do this would be to say that role is the reserved key in the JWT for PostgREST, if you issue a role claim in JWT it will switch to that role, if not, (and if you've used a certain command line argument when deploying), it will instead call the postgrest_auth function after setting the other claims in the JWT which it will expect to have the side effect of switching the session to another role.

I suppose this is more of a feature request, and I'm not sure if this would be more complicated to implement than I think, but if it is as easy as I think it would be a nice feature. While it might not be optimal for eventual speed of session auth etc, it is a starting point for that that could work well and securely for a while for a developer, if they're scaling perhaps they'd switch to a quicker option or something, but the complexity involved with this is orders of magnitude less than other options for session auth, which seems like a relatively common use case.

@eric-brechemier
Copy link
Contributor

It could be helpful to have a set of extension points defined in SQL, at the interface between PostgREST and PostgreSQL:

  • an optional function to set role based on JWT (this issue)
  • an optional function to create the JWT from the jwt_claims
  • an optional function to serialize the response (issue Support raw binary output (and input) #506)

@diogob
Copy link
Contributor

diogob commented Jun 8, 2016

Why would you want a session authentication exactly?
It seems to me that any session-related state can be encoded within the JWT in the format of claims.
As for passing a user as a parameter, why not handle in the views/procedures logic?

@begriffs
Copy link
Member

begriffs commented Oct 3, 2016

The master branch now supports a parameter called --pre-request. You give it the name of a schema-qualified stored procedure and it will call the procedure right after authentication but before the any data is fetched. This function can do anything it wants, including changing to another role or raising exceptions to stop the request.

@begriffs begriffs closed this as completed Oct 3, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement a feature, ready for implementation
Development

No branches or pull requests

4 participants