-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Verify JWTs without changing role #3002
Comments
Is there anything in the token payload that is constant, i.e. the same for every token? You could just extract that and add a role with this name to your database and then use that. Alternatively, if you could add such a constant payload to all the tokens, you could do something like |
Hi @wolfgangwalther! There are a variety of fields in our JWT payload that pertain to user-specific details. Due to the dynamic nature of these fields, they can differ and change frequently for individual users, making it a challenge to use them for consistent role determination. Additionally, we face another challenge. For security reasons, the JWKS are updated at regular intervals. They cannot remain static, so we need to access the endpoint where the JWKS are exposed. Could you kindly confirm whether the PGRST_JWT_SECRET field has the capability to accept a URL as a parameter? Thanks in advance. |
You might be looking for what was discussed here as well: #2725 (comment) |
Something similar had been requested here: #2690 |
Thinking more about this, I believe we should allow it. Right now we could say that PostgREST includes a builtin create function pre_request("request.role" name) returns void as $$
-- do set_config if you wish
$$ language sql;
alter role authenticator set pgrst.db_pre_request to 'pre_request'; Meaning the user is free to set the role obtained from the JWT using the role-claim-key. Once the @wolfgangwalther WDYT? Maybe the parameter could be just Related to #1941 |
If we want to disable setting the role via PostgREST, I think the easiest way to do so, would be to allow setting The JWT would still be checked, of course. The user can then write a pre-request function if they want to - or not. If they need any claim from the JWT, they could use a However, I would not tie "setting the role" to "a pre-request function with a specific argument exists". That's really awkward. |
That sounds good. I like the idea of making our default
Right, maybe we need a config like |
As for this issue, then the conclusion would be to allow doing:
Currently jwt-role-claim-key always takes a default
postgrest/src/PostgREST/AppState.hs Lines 79 to 82 in 6c3d7a9
Then postgrest/src/PostgREST/Query.hs Lines 249 to 251 in 6c3d7a9
|
Yes and no. How do you set this to Nothing via environment variable? How via in-database config? Where is the difference between not setting those, setting them to Nothing and to the default value? I'm not sure this will actually work like that. So maybe we need a |
Although.. every proper value for that config option needs to start with |
Wouldn't be opposed to that, but since we're talking about the tx settings, wouldn't be better to come up with a general Related to #1941 (comment) |
Oh.. I start to understand where you were coming from with your proposal in #3002 (comment). Basically you are saying I think we should really keep them separated. |
Correct. That's why I think
Yeah, I've closed previous issues with the same argument before but users want more flexibility nowadays. Maybe this allows us to extend our authN system too. And |
I am not saying we shouldn't make it configurable. I'm just saying "whether to |
Environment
Description of issue
Hello,
I'm currently attempting to integrate PostgREST into a system that employs its own OAuth2 for securing the service. The challenge I'm facing is that the JWT payload we send to PostgREST doesn't contain the user's role. Due to security constraints, we retrieve role-related information using an alternative method. This creates an issue for us. From my understanding (please correct me if I'm mistaken), this role claim seems to be mandatory when using a third-party OAuth to identify the role that should be assigned in the database. However, in our scenario, there shouldn't be any role or permission distinctions. Only authorized users can log into our application, and being logged in implies they have full access. For this reason, we also don't see a need for an anonymous user, as we don't want anyone accessing without authentication. Our application is straightforward with limited functionalities. That's why we're looking to achieve this behavior with PostgREST.
I conducted several tests using the .sub (usercode) and created a role in the database that matches my usercode, granting it the necessary permissions. This approach worked. However, given the dynamic nature of various fields in our JWT payload that pertain to user-specific details, it becomes unfeasible to maintain individual roles based on this token information. This leads me to the core of my inquiry: Is there a way that if the PGRST_JWT_ROLE_CLAIM_KEY environment variable isn't specified, PostgREST would simply verify the JWT's signature against the JWKS specified in the PGRST_JWT_SECRET environment variable?
In essence, we're looking for PostgREST to handle just the JWT verification and use the default permissions of the main user. Furthermore, we'd like to explore solutions that don't involve implementing a custom PostgreSQL function in our database, if possible.
Docker-compose setup
Setup database:
With this setup, when I am the logged-in user and we send that JWT, PostgREST verifies the role against the database, assigns it, and with the necessary permissions set on it, the generated endpoints work correctly. However, when we disable the PGRST_JWT_ROLE_CLAIM_KEY environment variable, we receive a 401 Unauthorized response with the following body:
And the header reads:
For us, it would be ideal to know if there's a possibility for PostgREST to simply validate the JWT token against the JWKS for signature verification. If that's successful, and in the absence of a role claim and no anonymous role, we'd like to use the primary user for all operations. This would allow us to bypass the chameleon functionality, as it wouldn't be necessary in our case.
(Expected behavior vs actual behavior)
(Steps to reproduce: Include a minimal SQL definition plus how you make the request to PostgREST and the response body)
1. Setup PostgREST Configuration:
Define the following environment variables:
Omit Role Claim Key:
Ensure that the PGRST_JWT_ROLE_CLAIM_KEY environment variable is not set.
Disable Anonymous Role:
Comment out or omit the following line to deactivate the anonymous role:
2. Database configuration
Execute the following SQL command to set up the required role in your database:
Note: Also add permissions to schemas/tables where necessary.
3. Make a Request:
Send a request to an exposed PostgREST endpoint, passing the JWT token in the 'Authorization' header.
4. Observe the Error:
The response body should be:
The text was updated successfully, but these errors were encountered: