-
Notifications
You must be signed in to change notification settings - Fork 0
PostgREST JWT Authentication
Beau Barker edited this page Nov 5, 2025
·
32 revisions
Implement secure JWT-based authentication in SuperStack.
An /rpc/login PostgREST endpoint issues an access token.
Generate a secret:
Note
PostgREST can share the JWT secret with Caddy. If you've already created a JWT secret for Caddy, use that.
openssl rand -base64 32Put the secret in the environment file:
app/.env
# JWT secret used by both Caddy and PostgREST
JWT_SECRET=(your secret)Add the secret and other settings to the Compose file:
app/compose.yaml
caddy:
environment:
JWT_SECRET: ${JWT_SECRET:?}
postgrest:
environment:
PGRST_APP_SETTINGS_JWT_EXP: 3600 # PostgREST default is no expiry!
PGRST_JWT_SECRET: ${JWT_SECRET:?}
PGRST_JWT_SECRET_IS_BASE64: true
postgres:
environment:
JWT_SECRET: ${JWT_SECRET:?}Split your Caddyfile into sections, Public (no auth) and JWT, where a
valid access token is required:
app/caddy/Caddyfile
{$CADDY_SITE_ADDRESS}
# --- Public ---
# PostgREST's public RPC endpoints
@auth {
path /rpc/login /rpc/logout /rpc/refresh_token
}
handle @auth {
reverse_proxy http://postgrest:3000
}
# PostgREST's OpenAPI endpoint
handle_path /rest/ {
reverse_proxy http://postgrest:3000
}
# --- JWT Protected Routes ---
route {
# Set the Authorization header from the Cookie header (for PostgREST)
# Only if it's not already set
@noHeader not header Authorization *
route @noHeader {
request_header Authorization "Bearer {cookie.access_token}"
}
# Non-public PostgREST endpoints
handle /rpc/* {
reverse_proxy http://postgrest:3000
}
handle_path /rest/* {
reverse_proxy http://postgrest:3000
}
# .. Other private endpoints ..
}Restart Caddy for the changes to take effect:
docker compose up -d --force-recreate caddy