auth
auth copied to clipboard
GOTRUE_JWT_SECRET value and base64 string format
Improve documentation
Link
Describe the problem
Overview
There is a missing information in docs in what format should be the JWT secret in GOTRUE_JWT_SECRET
environment variable. In README.md
there is an information that:
The secret used to sign JWT tokens with.
This is not always true. Given value is not always used to sign the token. It can be sometimes decoded from base64, if the secret is a valid base64 string before signing the token.
Let's use the JWT website to verify the secret value.
Prerequisites
Sharing the compose.yaml
for easier reproduction:
services:
postgres:
image: postgres:16-alpine
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=password
- POSTGRES_USER=postgres
- POSTGRES_DB=postgres
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
interval: 5s
timeout: 5s
retries: 5
volumes:
- ./01-init.sql:/docker-entrypoint-initdb.d/01-init.sql
gotrue:
image: supabase/gotrue:v2.157.0
depends_on:
postgres:
condition: service_healthy
ports:
- 9999:9999
environment:
- API_EXTERNAL_URL=http://localhost:9999
- GOTRUE_API_HOST=0.0.0.0
- GOTRUE_API_PORT=9999
- GOTRUE_DB_DRIVER=postgres
- GOTRUE_DB_DATABASE_URL=postgres://supabase_auth_admin:password@postgres:5432/postgres?sslmode=disable
- GOTRUE_DISABLE_SIGNUP=false
- GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED=true
- GOTRUE_EXTERNAL_EMAIL_ENABLED=true
- GOTRUE_JWT_ADMIN_ROLES=admin,service_role
- GOTRUE_JWT_AUD=authenticated
- GOTRUE_JWT_EXP=3600
- GOTRUE_JWT_SECRET=<paste_secret_here>
- GOTRUE_SITE_URL=http://localhost:9999
- GOTRUE_URI_ALLOW_LIST=*
And the database 01-init.sql
script:
CREATE USER supabase_admin
LOGIN
CREATEROLE
CREATEDB
REPLICATION
BYPASSRLS;
CREATE USER supabase_auth_admin
NOINHERIT
CREATEROLE
LOGIN
NOREPLICATION
PASSWORD 'password';
CREATE SCHEMA IF NOT EXISTS auth AUTHORIZATION supabase_auth_admin;
GRANT CREATE ON DATABASE postgres TO supabase_auth_admin;
ALTER USER supabase_auth_admin SET search_path = 'auth';
Verification
Take into account two scenarios:
# Scenario 1
# Non base64 string
GOTRUE_JWT_SECRET=secret
# Scenario 2
# base64 string
GOTRUE_JWT_SECRET=aaaa
Create anonymous user to get the JWT access_token
.
curl -X POST -H "Content-Type: application/json" -d '{}' http://localhost:9999/signup
Scenario 1
# Scenario 1
# Non base64 string
GOTRUE_JWT_SECRET=secret
If the secret
is used then signature is verified.
Scenario 2
# Scenario 2
# base64 string
GOTRUE_JWT_SECRET=aaaa
If the aaaa
string is used then signature is not verified. But the token can be successfully verified if the secret base64 encoded
option is checked.
Describe the improvement
At least there should be an annotation in documentation that GOTRUE_JWT_SECRET
should always be passed as the base64 encoded string. Without that information the behaviour of software is unpredictable. It can be confusing for the user that tried to sign the token using aaaa
value, but in fact the aaaa
was transformed to i
and i
was used to sign the token.
Additional context
N/A