-
Notifications
You must be signed in to change notification settings - Fork 0
PostgREST JWT Authentication
Enabling JWT authentication in PostgREST forces clients to authenticate using a JWT token in the Authorization header:
Authorization: Bearer eyJhbGciOiJIUzI1...
The minimal JWT payload must include at least a role.
{
"role": "user"
}Until JWT authentication is enabled (pgrst.jwt_secret set), PostgREST is not
secured and anyone can access it.
Note
PostgREST can share the JWT secret with Caddy.
Generate a secret:
openssl rand -base64 32Put the secret in the environment file:
app/.env
JWT_SECRET=(your secret)Add the secret to the PostgREST service:
postgrest:
environment:
PGRST_JWT_SECRET: ${JWT_SECRET:?}
PGRST_JWT_SECRET_IS_BASE64: trueThe secret is needed in the Postgres service because a migration will configure PostgREST:
db/.env
JWT_SECRET=(your secret)db/compose.yaml
postgres:
environment:
JWT_SECRET: ${JWT_SECRET:?}Add to the Postgrest initialisation migration:
db/postgres/migrations/00-init_postgrest.sql
\set pgrst_jwt_secret '$JWT_SECRET'
-- Set the JWT secret in the db - despite it being set in the JWT_SECRET
-- env var, this appears to be also required
alter system set pgrst.jwt_secret = :'pgrst_jwt_secret';cd db
bin/postgres migrateSplit your Caddyfile into public and JWT-protected sections. The private
routes require a valid access token:
app/caddy/Caddyfile
{$CADDY_SITE_ADDRESS}
# --- Public routes ---
# PostgREST's OpenAPI endpoint (an optional public endpoint)
handle_path /rest/ {
reverse_proxy http://postgrest:3000
}
# --- JWT protected routes ---
route {
# Set the Authorization header from the Cookie header
# Only if it's not already set
@noHeader not header Authorization *
request_header Authorization "Bearer {cookie.access_token}" # fallback to cookie
# Protected PostgREST endpoints
handle_path /rest/* {
reverse_proxy http://postgrest:3000
}
handle /rpc/* {
reverse_proxy http://postgrest:3000
}
# .. Other authenticated endpoints ..
}Restart Caddy for the changes to take effect:
docker compose up -d --force-recreate caddy- Continue to PostgREST JWT Management to manage the generation and refreshing of tokens within PostgREST itself.
- Consider enabling Caddy JWT as well, at the API gateway level, to protect other services as well. It can use the same secret, so a single JWT can be used across all services in addition to PostgREST.