supabase / supabase-js

An isomorphic Javascript client for Supabase. Query your Supabase database, subscribe to realtime events, upload and download files, browse typescript examples, invoke postgres functions via rpc, invoke supabase edge functions, query pgvector.
https://supabase.com
MIT License
2.86k stars 220 forks source link

How to set/get the JWT secret? #25

Closed hansy closed 3 years ago

hansy commented 3 years ago

Question

Is there a way to get or set the secret used to sign the JWT access tokens? My use case is to use the Supabase-generated tokens for authorization in other micro-services, so having the secret will help verify their signatures.

awalias commented 3 years ago

hey @hansy , the secret is available in your database, run show app.settings.jwt_secret; in the SQL editor to view it

there is no ability to set it yet (you could set this value in the database but it would not update on the supabase api server yet, we should build this capability in)

kiwicopple commented 3 years ago

we should build this capability in

For a first step we could even just expose it (read only) so that devs can get it easily. Should we put it down in the "Settings" section with the API keys? Or in the "Auth" section?

My initial thought is in the "Settings" - down where the developers will live. The "Auth" section might be more "business user" config

hansy commented 3 years ago

As long as devs know how to get the secret (via the SQL editor is more than fine), this isn't a huge priority. Thanks for yall's prompt response.

This might be a separate discussion but I can't seem to validate a token signature with the secret obtained from the editor. And this even after turning the secret back into a byte array (the way GoTrue signs the tokens: https://github.com/netlify/gotrue/blob/c2a56b766367217c280c80851d79af68f0031a5a/api/token.go#L166).

package main

import (
    "fmt"
    "github.com/dgrijalva/jwt-go"
)

var jwtSecret = []byte("secret")
var token = "<ACCESS TOKEN HERE>"

func VerifyToken(tokenString string) (c jwt.MapClaims, err error) {
    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        return jwtSecret, nil
    })

    if !token.Valid {
        return
    }
    tokenMap, _ := token.Claims.(jwt.MapClaims)
    return tokenMap, err
}

func main() {
    fmt.Println(VerifyToken(token)) // Prints: map[] signature is invalid
}

If anyone knows off the top of their head what I'm doing wrong, direction would be appreciated. Otherwise I'll plug away at this and report my findings for anyone else interested in using the JWT secret for signature verification.

kiwicopple commented 3 years ago

@phamhieu could we expose this in a new panel on the API settings? (read only for now)

image

@awalias any thoughts on the signature validation? Can you replicate on GoTrue?

phamhieu commented 3 years ago

@hansy your code works for me.

Screenshot 2020-09-01 at 3 53 23 PM

@kiwicopple I will update the UI to show JWT secret

hansy commented 3 years ago

@phamhieu huh weird it didn't for me, but I'll take your word for it. That's good news! Thanks for your help!

kiwicopple commented 3 years ago

Also the UI is showing the secret now @hansy - Hiue made the updates a few days back.

If you're happy with this, feel free to close!

kiwicopple commented 3 years ago

Closing for now - feel free to reopen

RobertB4 commented 2 years ago

Is there any way to get the JWT secret during local development? My hosted version of supabase shows the JWT secret with show app.settings.jwt_secret;, but my local version does not.

ERROR:  unrecognized configuration parameter "app.settings.jwt_secret"
soedirgo commented 2 years ago

@RobertB4 it's undocumented, but the local dev's JWT secret is hardcoded to super-secret-jwt-token-with-at-least-32-characters-long.

kengru commented 8 months ago

@soedirgo thank you so much, I saw that on the console and didn't even bothered to think it was that 😄

thomergil commented 8 months ago

I got in touch with Supabase support. If you're using the Supabase CLI, the environment variable you must set in .env is SUPABASE_AUTH_JWT_SECRET.

$ grep JWT_SECRET .env
SUPABASE_AUTH_JWT_SECRET=something-boring-and-repetitive-boring-and-repetitive

$ yarn run supabase stop; yarn run supabase start
[...]
Started supabase local development setup.

         API URL: http://localhost:54321
     GraphQL URL: http://localhost:54321/graphql/v1
          DB URL: postgresql://postgres:postgres@localhost:54322/postgres
      Studio URL: http://localhost:54323
    Inbucket URL: http://localhost:54324
      JWT secret: something-boring-and-repetitive-boring-and-repetitive

You can then use the form at https://supabase.com/docs/guides/self-hosting#api-keys to compute ANON_KEY.

huyouare commented 1 month ago

I'm able to set the JWT secret via the UI for a hosted instance but not via the SQL Editor (getting ERROR: 42501: permission denied to set parameter "app.settings.jwt_secret") when running:

alter database postgres
set
  "app.settings.jwt_secret" to 'super-secret-jwt-token-with-at-least-32-characters-long';