-
Notifications
You must be signed in to change notification settings - Fork 0
Service JWT
Beau Barker edited this page Dec 12, 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.
You can use this script to generate a service JWT:
base64-to-jwt.sh
#!/usr/bin/env bash
#
# base64-to-jwt.sh — Create an HS256 JWT using a base64-encoded secret key.
#
# Usage:
# ./base64-to-jwt.sh <base64_secret> [payload_json] [algorithm]
#
# Example:
# ./base64-to-jwt.sh 'rzIw/CmtdWD9IaNgGigcaFFFuBDTbJ4ZyCkZvWmSrqk=' \
# '{"role":"service","sub":"service"}'
#
# ./base64-to-jwt.sh "$JWT_SECRET" '{"role":"service"}' HS512
#
set -euo pipefail
SECRET_B64="${1:-}"
PAYLOAD_JSON=${2:-'{"role":"service","sub":"service"}'}
ALG="${3:-HS256}"
if [[ -z "$SECRET_B64" ]]; then
echo "Usage: $0 <base64_secret> [payload_json] [algorithm]" >&2
exit 1
fi
# --- Build header/payload base64url ---
b64url() {
openssl base64 -e -A | tr -d '\n' | tr '+/' '-_' | tr -d '='
}
HEADER=$(printf '{"alg":"%s","typ":"JWT"}' "$ALG" | b64url)
PAYLOAD=$(printf '%s' "$PAYLOAD_JSON" | b64url)
DATA="$HEADER.$PAYLOAD"
# --- Decode base64 secret to hex for OpenSSL ---
KEY_HEX=$(printf '%s' "$SECRET_B64" | base64 -d | xxd -p -c256)
# --- Sign and produce signature in base64url ---
SIG=$(printf '%s' "$DATA" \
| openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:"$KEY_HEX" \
| b64url)
echo -n "$DATA.$SIG"Run it:
chmod +x base64-to-jwt.sh./base64-to-jwt.sh your-secret
eyJhbGciOiJIUzI1NiIsIn...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:?}Create a role and grant permissions.
db/postgres/migrations/90-service_role.sql
create role service noinherit nologin;
grant service to authenticator;
grant usage on schema api to service;
grant select, insert, update on table api.account to service;