Skip to content
Beau Barker edited this page Nov 5, 2025 · 17 revisions

A service JWT is a token that authenticates a backend service — not a human user.

Use it when one internal component (for example, an api endpoint or background job) needs to securely talk to another (like PostgREST or the API gateway) without going through login or cookies.

Create a token

Create a jwt (you can use jwt.io):

Set the header to:

{
  "alg": "HS256",
  "typ": "JWT"
}

Set the payload:

{}
  • Caddy-jwt's minimal payload is an empty object.
  • PostgREST's payload must contain a role.

Secret:

your-secret

Grab the generated token and put it into .env:

app/.env

SERVICE_JWT=eyJhbGciOiJIUzI1NiIsIn...

Add it to services that need it:

app/compose.yaml

api:
  environment:
    SERVICE_JWT: ${SERVICE_JWT:?}

PostgREST

PostgREST needs a service role.

db/postgres/migrations/04-roles.sql

create role service noinherit nologin;

db/postgres/migrations/05-grants.sql

-- Service role
grant service to authenticator;
grant usage on schema api to service;
grant select,insert,update on table api.account to service;

Clone this wiki locally