Postgrest: JWKS: load public keys from a well known endpoint

Created on 13 Jun 2018  路  12Comments  路  Source: PostgREST/postgrest

Please see https://auth0.com/docs/jwks

Auth0 exposes a JWKS endpoint for each tenant, which is found at https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json. This endpoint will contain the JWK used to sign all Auth0 issued JWTs for this tenant.

It would be great of PostgREST could load the public key from such an endpoint.

config

Most helpful comment

It would be really awesome if we could load JWK key sets from URLs instead of local files such as:

https://www.googleapis.com/robot/v1/metadata/jwk/[email protected]

This would prevent operator error in remembering to rotate those key sets once they expire as well---PostgREST should be able to reload them from the URL on expiration.

All 12 comments

Or ... you install postgrest as a system service (https://docs.subzero.cloud/production-infrastructure/ubuntu-server/) and use systemd ExecStartPre directive to run one curl call that places that key in the file postgrest is configured to read...

@purpleKarrot Did you get PostgREST to work with the JWK from Auth0 in general? I copied the first key in mytenant.auth0.com/.well-known/jwks.json into a file and set jwt-secret = "@thefile" in the config file as describe in the docs here.
Unfortunately PostgREST still always responds with

{
    "message": "JWSError JWSInvalidSignature"
}

Edit: I just found the solution: https://github.com/frasertweedale/hs-jose/issues/56#issuecomment-332559979

i was just about to ask something similar. does the jwk accepts the x5u parameter. i tried authenticating with firebase ID token (jwt signed with asymetrical RSA) and only could make it work with a node js library to transform the cert into a "standard" jwk [jwk]. wich is not very maintainable because google has 2 public keys wich are going to change periodically.
here are the keys (x5u compliant )
google public key

i made a nodejs script to fectch the certs and mint a jwks, the individual jwk work but when i put them both in a jwks it stops validating. im guessing this is not suported. i can get by because luckyly all of the jwt provided by google firebase had been of the same "kid" so im using just one key. any info would be welcome.

@jcozain Yes, PostgREST seems to only support single JSON Web Keys at the moment, not JSON Web Key Sets.
I am using jq to extract the first JWK and remove the properties that hs-jose currently seems to be incompatible with (namely x5c and x5t).

wget --quiet -O - https://yourcompany.eu.auth0.com/.well-known/jwks.json \
    | jq " {
               alg: .keys[0].alg,
               kty: .keys[0].kty,
               use: .keys[0].use,
               n: .keys[0].n,
               kid: .keys[0].kid,
               e: .keys[0].e
               }

               " > rsa.jwk.pub

Or ... you install postgrest as a system service (https://docs.subzero.cloud/production-infrastructure/ubuntu-server/) and use systemd ExecStartPre directive to run one curl call that places that key in the file postgrest is configured to read...

Is there a straightforward way to make this happen with the docker image?

Another solution for supporting firebase auth (or auth0), without worrying about JWKS support:

  • put PostgREST behind nginx
  • In nginx, use auth_request to have it reach out to a custom made backend that validates auth tokens (e.g. using firebase auth's admin lib); proxy responds with a custom-proxy-user response header
  • Use auth_request_set $auth_user $upstream_http_custom_proxy_user; and proxy_set_header to pass it on to PostgREST
  • use that instead of the JWT claim

Does this mean that JWT handling is another thing that PostgREST doesn't need to do? :-)

How would you set a role without a JWT claim?

I meant that tongue-in-cheek. You could simply pass the role as another, unsigned, response header. Which, I think, would be fine in an environment where postgrest is behind nginx.

(In my case, I ended up generating a JWT in my auth proxy and passing that to postgrest, because JWTs are well integrated with the role system.)

It would be really awesome if we could load JWK key sets from URLs instead of local files such as:

https://www.googleapis.com/robot/v1/metadata/jwk/[email protected]

This would prevent operator error in remembering to rotate those key sets once they expire as well---PostgREST should be able to reload them from the URL on expiration.

For the meantime, @rockodragon shared a nodejs solution on gitter chat: https://gitter.im/begriffs/postgrest?at=5ea5106b568e5258e4852dbc

@rockodragon thanks! I made something similar in Python, but don't have a great place to run it right now.

Was this page helpful?
0 / 5 - 0 ratings