-
-
Notifications
You must be signed in to change notification settings - Fork 1.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
JWKS: load public keys from a well known endpoint #1130
Comments
Or ... you install postgrest as a system service (https://docs.subzero.cloud/production-infrastructure/ubuntu-server/) and use systemd |
@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
Edit: I just found the solution: frasertweedale/hs-jose#56 (comment) |
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. |
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.
|
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:
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. |
By the way, if you loaded the the key sets from that URL, wouldn't you run the the risk of authorizing any firebase user to access your postgrest? You'd need another mechanism to restrict it to your audience? |
I'd like to share my solution. I wrote this to integrate PostgREST with ZITADEL (an open-source Auth0 alternative). https://gist.github.com/bohanyang/aabb562ad12906ff13420a907c87d2ca |
I dont like the idea of using database for config. So I did this
(fetch_jwk.sh) #!/bin/sh
# Fetch the JWK secret from the Supertokens API server
JWK_RESPONSE=$(curl -s http://127.0.0.1:3000/auth/jwt/jwks.json)
# Escape the JWK response for the config file
ESCAPED_JWK_RESPONSE=$(echo "$JWK_RESPONSE" | jq -sRr @json)
# Update postgrest.conf
cat <<EOF > /app/postgrest.conf
db-uri = "$DATABASE_URL"
db-schema = "ploton_api"
db-anon-role = "web_anon"
jwt-secret = $ESCAPED_JWK_RESPONSE
server-port = 9000
server-host = "0.0.0.0"
server-cors-allowed-origins="$ALLOWED_CORS"
EOF
# Reload PostgREST
killall -SIGUSR2 postgrest crontab
Basically updating the config file and then notifying postgrest about the config reload. |
Nice, thanks for sharing. You can avoid rewriting the whole config file and also the escaping the secret by just writing the secret to a separate file and then including it via |
oh nice. I didn't know about the filepath. Thanks for sharing. |
Thanks @hiteshjoshi. I can share an iteration on your solution that includes some simplifications: Set Dockerfile
crontab
update_jwk.sh
|
@steve-chavez Would it align with the ethos of the project to include dynamic JWKS loading from a well-known endpoint directly in PostgREST? Or is it preferable for such functionality to be handled as an external exercise as implemented here? |
To be honest, I don't see the value, really. The example above is essentially a single cron line and single curl call. I was thinking back and forth between adding a full solution (which would need to support scheduling + the request) or a more generic solution (just automatic reloading after an interval and then calling a custom command)... but I can't come up with anything that really makes the effort to implement this worth it. |
In my case, the added value would be being able to just set some environment vars & run PostgREST. Now i have to add some cruft in my I see less value in automatically refreshing, but the loading part would save everybody that uses PostgREST with JWKS a trip to this here ticket. |
I see the value - if we could make sure it works reliably. Since the "well known JWKS" is not standardized anywhere, I think, I feat that we might end up not being able to support all use-cases. Some might need custom headers. Some might need filters like in your example (where you use My next idea then was to support something like a So yeah, I don't know what's the best way to proceed. |
Automatically refreshing would allow rotating keys without restarting too. It seems like most things have standardized on fetching the JWK for this reason, from what I've seen. |
This can be achieved already with the solutions proposed / posted above. You don't need built-in JWKS fetching for it. |
Yes but it's not easy. I spent 2-4 hours today trying to figure out the right |
This is kind of the point that I was looking for - but haven't found anything. Is there any kind of standard for this? If there was, there would be a lot more reason to implement something based on that. Doesn't even need to be an RFC, just something that writes up what "everyone" is doing. We don't want to build something that only works in some cases, but not others. |
To my knowledge this has been written up in the OpenID spec. You can request [OpenID configuration](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig) to get a [`jwks_uri`](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata)
|
Aha! Now.. would we add support for querying OpenID configuration and then fetch jwks_uri on top? Or would we only support jwks_uri directly? It seems like setting the OpenID config URL might make more sense, WDYT? |
Yeah i agree. It seems querying the OpenID connect endpoint is the way others are handling this to. For example: OpenSearch, Minio. |
I've been trying to figure a way out, and came up with https://github.com/edgeflare/edge/blob/main/internal/util/postgrest/rotate-jwt.go.go and calling it like func main() {
ctx := context.Background()
pool, _ := pgxpool.New(ctx, os.Getenv("CONN_STRING"))
err := postgrest.RotateJwtKey(ctx, pool, os.Getenv("ZITADEL_JWK_URL"))
if err != nil {
log.Fatalln(err)
}
} |
Please see https://auth0.com/docs/jwks
It would be great of PostgREST could load the public key from such an endpoint.
The text was updated successfully, but these errors were encountered: