Document more explicitly that a token without `aud` will still be accepted with a `jwt-aud` setting
Environment
- PostgreSQL version: 13.1
- PostgREST version: v9.0.0 docker postgrest/postgrest:v9.0.0
- Operating system: Windows 10, Running PostgREST/PostgreSQL via Docker
Description of issue
I have PostgREST running with a jwt-aud config set via Docker with PGRST_JWT_AUD to testing456. I've tried four things; and the fourth one is where I think there is a bug.
- JWT with
"aud": [], an emptyaud, fails withJWTNotInAudience, which is correct. - JWT with
"aud": ["testing123"], the wrongaud, fails withJWTNotInAudience, which is correct. - JWT with
"aud": ["testing123, testing456"], with the correctaud, succeeds, which is correct. - JWT without an
"aud"parameter, and thus the correctaudoftesting456is not defined, succeeds; which I think should fail; right?
It looks like if you specify PostgREST with an jwt-aud, but generate JWTs without an "aud" field, they still have access to the server anyway. I would expect once PostgREST specifies jwt-aud in the config; it must be in the JWT to provide access.
Is this required according to the JWT spec? I am planning on having a lot of PostgREST servers running; and if I accidently generate a JWT without an "aud" field it would have wide ranging access.
Thanks!
The RFC says, that the aud parameter is optional:
The interpretation of audience values is generally application specific. Use of this claim is OPTIONAL.
Our docs say this:
jwt-aud
Specifies the JWT audience claim. If this claim is present in the client provided JWT then you must set this to the same value as in the JWT, otherwise verifying the JWT will fail.
I don't really see a violation of the RFC and the docs describe this also just like you describe it. I don't see a bug here.
Thanks for the response @wolfgangwalther. I assumed that when PostgREST specifies an jwt-aud, the JWT would also need to specify that aud to be valid. Perhaps having one of the "red boxes" in the docs explicitly calling that out would help as this behavior still caught me by surprise. Interested in how others think.
Anyhoo, I was able to solve this by adding the following in my pre-request function with the following:
if current_setting('request.jwt.claims', true)::json ->> 'aud' is null then
raise insufficient_privilege using detail = 'Invalid aud', hint = 'Your session does not represent a valid aud.';
end if;
I could see this behavior being usefull to allow for 'blank-check, non-aud` JWTs as well as allowing applications to specify more constrained access if they desire.
Thanks!
I could see this behavior being usefull to allow for 'blank-check, non-aud` JWTs as well as allowing applications to specify more constrained access if they desire.
Yeah, I guess that's the idea here.
I assumed that when PostgREST specifies an jwt-aud, the JWT would also need to specify that aud to be valid. Perhaps having one of the "red boxes" in the docs explicitly calling that out would help as this behavior still caught me by surprise.
That sounds like a good idea - I'll transfer this to the docs repo to keep track of this suggestion there.