GOTRUE_JWT_SECRET value and base64 string format

Open
#1,758 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
1/5
Estimated time
1-3 hours
Newbie friendliness
55/100
Issue type
Documentation
Clarity
Clearly specified
Activity status
Stale
Tech stack
go

Research direction

README.md is the named entry point; read the GOTRUE_JWT_SECRET section and compare its wording with the reported secret and aaaa scenarios. Done means the documentation clearly states the expected secret format and explains the base64 decoding behavior described in the issue.

Written by the indexing model from the issue text.

Description

documentation

Improve documentation

Link

README.md

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

image

If the secret is used then signature is verified.

Scenario 2
# Scenario 2
# base64 string
GOTRUE_JWT_SECRET=aaaa

image

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.

image

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

Dominant language
Go
Stars
2.6k
Forks
764
Avg merge
5d 3h
Merged PRs (30d)
39

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from supabase/auth

All issues in supabase/auth

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.