Skip to content

Allow schema selection from JWT claims (like role) #4608

@code-flu

Description

@code-flu

Problem
Currently, PostgREST can dynamically add new schemas at runtime, but selecting which schema a request hits still requires the client to specify it via Accept-Profile or URL. This exposes schema names to clients and makes fully hidden multi-tenant routing impossible.

What I tried
I configured PostgREST to use a pre-request function:

create or replace function postgrest.set_schema_from_jwt()
returns void as $$
declare
  schema_name text := current_setting('request.jwt.claims', true)::json->>'namespace';
begin
   if schema_name is not null and schema_name <> '' then
    perform set_config('search_path', schema_name, true);
  else
    raise exception 'Invalid or corrupted JWT';
  end if;
end;
$$ language plpgsql;

And set it in the environment:

PGRST_DB_PRE_REQUEST="postgrest.set_schema_from_jwt"

However, this does not work for routing endpoints because it runs after PostgREST has already planned the query. Changing search_path at this point only affects functions or views, not which schema the endpoint resolves to.

Use case

  • Each tenant has its own schema
  • JWT contains the tenant identity or role (e.g., "namespace": "schema_fd9d")
  • Requests should automatically go to the correct schema based on the JWT, without the client needing to set headers or URLs

Proposed feature
Add a configuration option, e.g.:

db-schema-claim = "namespace"

Behavior:

  • PostgREST reads the configured JWT claim before routing
  • Uses its value as the API schema for the request (like Accept-Profile)
  • Falls back to a default schema if the claim is missing or invalid

Benefits

  • Supports fully hidden multi-tenant routing
  • No need for clients to send headers
  • Works with dynamically added schemas
  • Keeps schema cache and OpenAPI generation deterministic
  • Compatible with JWT-based access control

Security considerations

  • JWT claims are signed and verified, so schema selection is trusted
  • Permissions still follow the role grants, same as current behavior

Metadata

Metadata

Assignees

No one assigned

    Labels

    authnRelated to authenticationconfigrelated to the configuration optionsideaNeeds of discussion to become an enhancement, not ready for implementation

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions